owebjs 1.5.7-dev → 1.5.9-dev
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +70 -4
- package/dist/index.d.ts +2 -0
- package/dist/structures/Oweb.js +24 -2
- package/dist/uwebsocket/response.js +15 -1
- package/dist/uwebsocket/server.js +27 -2
- package/package.json +1 -1
- package/0http.js +0 -8
- package/allahbeler2.png +0 -0
- package/allahbeyler.png +0 -0
- package/avatar.png +0 -0
- package/benchmark.txt +0 -191
- package/express.js +0 -14
- package/fasti.js +0 -14
- package/purehttp.js +0 -19
- package/uws.js +0 -16
package/README.md
CHANGED
|
@@ -72,10 +72,10 @@ second average
|
|
|
72
72
|
| Runtime | Version | Requests/sec |
|
|
73
73
|
| ------------------------- | --------- | -----------: |
|
|
74
74
|
| uWebSockets.js | 20.52.0 | 79,149 |
|
|
75
|
-
| **Oweb (uWS)** | 1.5.
|
|
75
|
+
| **Oweb (uWS)** | 1.5.8-dev | 76,853 |
|
|
76
76
|
| 0http | 4.4.0 | 46,605 |
|
|
77
77
|
| Fastify | 4.23.2 | 46,238 |
|
|
78
|
-
| **Oweb (Fastify)** | 1.5.
|
|
78
|
+
| **Oweb (Fastify)** | 1.5.8-dev | 42,570 |
|
|
79
79
|
| Node.js http.createServer | 24.5.0 | 42,544 |
|
|
80
80
|
| Express | 5.2.1 | 24,913 |
|
|
81
81
|
|
|
@@ -83,6 +83,72 @@ This is a synthetic "Hello, Word!" benchmark that aims to evaluate the framework
|
|
|
83
83
|
The overhead that each framework has on your application depends on your application.
|
|
84
84
|
You should always benchmark if performance matters to you.
|
|
85
85
|
|
|
86
|
+
## Best Performance
|
|
87
|
+
|
|
88
|
+
For the highest throughput, use these defaults:
|
|
89
|
+
|
|
90
|
+
- Enable uWebSockets runtime: `uWebSocketsEnabled: true`
|
|
91
|
+
- Disable powered-by header: `poweredByHeader: false`
|
|
92
|
+
- For headers that should be sent on every request (for example CORS-related headers), use `staticResponseHeaders` instead of per-request hooks
|
|
93
|
+
|
|
94
|
+
Example (production-oriented):
|
|
95
|
+
|
|
96
|
+
```js
|
|
97
|
+
import Oweb from 'owebjs';
|
|
98
|
+
|
|
99
|
+
const app = await new Oweb({
|
|
100
|
+
uWebSocketsEnabled: true,
|
|
101
|
+
poweredByHeader: false,
|
|
102
|
+
autoPreflight: true,
|
|
103
|
+
staticResponseHeaders: {
|
|
104
|
+
// CORS (set your real origin in production)
|
|
105
|
+
'access-control-allow-origin': 'https://yourdomain.com',
|
|
106
|
+
'access-control-allow-methods': 'GET,POST,PUT,PATCH,DELETE,OPTIONS',
|
|
107
|
+
'access-control-allow-headers': 'Content-Type, Authorization',
|
|
108
|
+
vary: 'Origin',
|
|
109
|
+
|
|
110
|
+
// Security headers
|
|
111
|
+
'x-content-type-options': 'nosniff',
|
|
112
|
+
'x-frame-options': 'DENY',
|
|
113
|
+
'referrer-policy': 'strict-origin-when-cross-origin',
|
|
114
|
+
'permissions-policy': 'geolocation=(), microphone=(), camera=()',
|
|
115
|
+
'cross-origin-opener-policy': 'same-origin',
|
|
116
|
+
'cross-origin-resource-policy': 'same-site',
|
|
117
|
+
},
|
|
118
|
+
}).setup();
|
|
119
|
+
|
|
120
|
+
await app.loadRoutes({
|
|
121
|
+
directory: 'routes',
|
|
122
|
+
hmr: {
|
|
123
|
+
enabled: false,
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
await app.start({ port: 3000, host: '0.0.0.0' });
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
## CORS Configuration
|
|
131
|
+
|
|
132
|
+
Use `autoPreflight` to return `204` for preflight requests and set CORS headers through `staticResponseHeaders`.
|
|
133
|
+
|
|
134
|
+
```js
|
|
135
|
+
import Oweb from 'owebjs';
|
|
136
|
+
|
|
137
|
+
const app = await new Oweb({
|
|
138
|
+
uWebSocketsEnabled: true,
|
|
139
|
+
autoPreflight: true,
|
|
140
|
+
poweredByHeader: false,
|
|
141
|
+
staticResponseHeaders: {
|
|
142
|
+
'access-control-allow-origin': 'https://yourdomain.com',
|
|
143
|
+
'access-control-allow-methods': 'GET,POST,PUT,PATCH,DELETE,OPTIONS',
|
|
144
|
+
'access-control-allow-headers': 'Content-Type, Authorization',
|
|
145
|
+
vary: 'Origin',
|
|
146
|
+
},
|
|
147
|
+
}).setup();
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
If you need credentials, do not use `*` for `access-control-allow-origin`; set an explicit origin.
|
|
151
|
+
|
|
86
152
|
## First App (2 Minutes)
|
|
87
153
|
|
|
88
154
|
Start with a minimal app, then we will add route conventions step by step.
|
|
@@ -124,7 +190,7 @@ routes/
|
|
|
124
190
|
[id].js
|
|
125
191
|
auth/
|
|
126
192
|
login.post.js
|
|
127
|
-
|
|
193
|
+
posts/
|
|
128
194
|
[id=integer].js
|
|
129
195
|
events/
|
|
130
196
|
sse.js
|
|
@@ -193,7 +259,7 @@ export default class LoginPostRoute extends Route {
|
|
|
193
259
|
|
|
194
260
|
Matcher params add filename-level validation.
|
|
195
261
|
|
|
196
|
-
`routes/
|
|
262
|
+
`routes/posts/[id=integer].js` + `matchers/integer.js`
|
|
197
263
|
|
|
198
264
|
```js
|
|
199
265
|
// matchers/integer.js
|
package/dist/index.d.ts
CHANGED
|
@@ -21,6 +21,8 @@ export { HTTPMethods } from 'fastify/types/utils';
|
|
|
21
21
|
interface OwebOptions extends FastifyServerOptions {
|
|
22
22
|
uWebSocketsEnabled?: boolean;
|
|
23
23
|
poweredByHeader?: boolean;
|
|
24
|
+
autoPreflight?: boolean;
|
|
25
|
+
staticResponseHeaders?: Record<string, string>;
|
|
24
26
|
OWEB_INTERNAL_ERROR_HANDLER?: Function;
|
|
25
27
|
}
|
|
26
28
|
interface LoadRoutesOptions {
|
package/dist/structures/Oweb.js
CHANGED
|
@@ -29,6 +29,7 @@ class Oweb extends _FastifyInstance {
|
|
|
29
29
|
this._options = options ?? {};
|
|
30
30
|
this._options.uWebSocketsEnabled ??= false;
|
|
31
31
|
this._options.poweredByHeader ??= true;
|
|
32
|
+
this._options.autoPreflight ??= false;
|
|
32
33
|
this._options.OWEB_INTERNAL_ERROR_HANDLER ??= (_, res, err) => {
|
|
33
34
|
return res.status(500).send({
|
|
34
35
|
error: err.message
|
|
@@ -61,7 +62,11 @@ class Oweb extends _FastifyInstance {
|
|
|
61
62
|
async setup() {
|
|
62
63
|
if (this._options.uWebSocketsEnabled) {
|
|
63
64
|
const serverimp = (await import("../uwebsocket/server.js")).default;
|
|
64
|
-
const server = await serverimp({
|
|
65
|
+
const server = await serverimp({
|
|
66
|
+
staticResponseHeaders: this._options.staticResponseHeaders,
|
|
67
|
+
autoPreflight: this._options.autoPreflight,
|
|
68
|
+
poweredByHeader: this._options.poweredByHeader
|
|
69
|
+
});
|
|
65
70
|
this.uServer = server;
|
|
66
71
|
this._options.serverFactory = (handler) => {
|
|
67
72
|
server.on("request", handler);
|
|
@@ -74,12 +79,29 @@ class Oweb extends _FastifyInstance {
|
|
|
74
79
|
if (!this._options.uWebSocketsEnabled) {
|
|
75
80
|
await fastify.register(websocketPlugin);
|
|
76
81
|
}
|
|
77
|
-
|
|
82
|
+
const staticHeaderEntries = this._options.staticResponseHeaders ? Object.entries(this._options.staticResponseHeaders) : [];
|
|
83
|
+
if (!this._options.uWebSocketsEnabled && (this._options.poweredByHeader || staticHeaderEntries.length)) {
|
|
84
|
+
fastify.addHook("onRequest", (_, res, done) => {
|
|
85
|
+
if (this._options.poweredByHeader) {
|
|
86
|
+
res.header("X-Powered-By", "Oweb");
|
|
87
|
+
}
|
|
88
|
+
for (let i = 0; i < staticHeaderEntries.length; i++) {
|
|
89
|
+
const [key, value] = staticHeaderEntries[i];
|
|
90
|
+
res.header(key, value);
|
|
91
|
+
}
|
|
92
|
+
done();
|
|
93
|
+
});
|
|
94
|
+
} else if (this._options.poweredByHeader) {
|
|
78
95
|
fastify.addHook("onRequest", (_, res, done) => {
|
|
79
96
|
res.header("X-Powered-By", "Oweb");
|
|
80
97
|
done();
|
|
81
98
|
});
|
|
82
99
|
}
|
|
100
|
+
if (this._options.autoPreflight && !this._options.uWebSocketsEnabled) {
|
|
101
|
+
fastify.options("/*", (_req, res) => {
|
|
102
|
+
return res.status(204).send();
|
|
103
|
+
});
|
|
104
|
+
}
|
|
83
105
|
const internalKV = this._internalKV;
|
|
84
106
|
fastify.addHook("onClose", async () => {
|
|
85
107
|
const watchers = internalKV.get(HMR_WATCHERS_KEY);
|
|
@@ -17,8 +17,9 @@ class HttpResponse extends Writable {
|
|
|
17
17
|
__headers;
|
|
18
18
|
headersSent;
|
|
19
19
|
finished;
|
|
20
|
+
staticHeaders;
|
|
20
21
|
_socket = null;
|
|
21
|
-
constructor(uResponse, uServer) {
|
|
22
|
+
constructor(uResponse, uServer, staticHeaders) {
|
|
22
23
|
super();
|
|
23
24
|
this.res = uResponse;
|
|
24
25
|
this.server = uServer;
|
|
@@ -27,6 +28,7 @@ class HttpResponse extends Writable {
|
|
|
27
28
|
this.__headers = {};
|
|
28
29
|
this.headersSent = false;
|
|
29
30
|
this.finished = false;
|
|
31
|
+
this.staticHeaders = staticHeaders;
|
|
30
32
|
}
|
|
31
33
|
get socket() {
|
|
32
34
|
if (!this._socket) {
|
|
@@ -62,6 +64,18 @@ class HttpResponse extends Writable {
|
|
|
62
64
|
if (this.headersSent || this.isClosed()) return;
|
|
63
65
|
const message = this.statusMessage || http.STATUS_CODES[this.statusCode] || "Unknown";
|
|
64
66
|
this.res.writeStatus(`${this.statusCode} ${message}`);
|
|
67
|
+
if (this.staticHeaders?.length) {
|
|
68
|
+
for (let i = 0; i < this.staticHeaders.length; i++) {
|
|
69
|
+
const [key, value] = this.staticHeaders[i];
|
|
70
|
+
if (key === "content-length" || key === "transfer-encoding") {
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
if (this.__headers[key] !== void 0) {
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
this.res.writeHeader(key, value);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
65
79
|
const keys = Object.keys(this.__headers);
|
|
66
80
|
for (let i = 0; i < keys.length; i++) {
|
|
67
81
|
const key = keys[i];
|
|
@@ -6,7 +6,7 @@ const REQUEST_EVENT = "request";
|
|
|
6
6
|
import HttpRequest from './request.js';
|
|
7
7
|
import HttpResponse from './response.js';
|
|
8
8
|
import http from "node:http";
|
|
9
|
-
async function server_default({ cert_file_name, key_file_name }) {
|
|
9
|
+
async function server_default({ cert_file_name, key_file_name, staticResponseHeaders, autoPreflight, poweredByHeader }) {
|
|
10
10
|
let uWS;
|
|
11
11
|
uWS = (await import("uWebSockets.js")).default;
|
|
12
12
|
let appType = "App";
|
|
@@ -22,6 +22,10 @@ async function server_default({ cert_file_name, key_file_name }) {
|
|
|
22
22
|
cert_file_name,
|
|
23
23
|
key_file_name
|
|
24
24
|
};
|
|
25
|
+
const normalizedStaticHeaders = staticResponseHeaders ? Object.entries(staticResponseHeaders).map(([k, v]) => [
|
|
26
|
+
k.toLowerCase(),
|
|
27
|
+
String(v)
|
|
28
|
+
]) : void 0;
|
|
25
29
|
const copyArrayBufferToBuffer = /* @__PURE__ */ __name((bytes) => {
|
|
26
30
|
const src = new Uint8Array(bytes);
|
|
27
31
|
const out = Buffer.allocUnsafe(src.byteLength);
|
|
@@ -33,6 +37,27 @@ async function server_default({ cert_file_name, key_file_name }) {
|
|
|
33
37
|
const query = req.getQuery();
|
|
34
38
|
const url = req.getUrl();
|
|
35
39
|
const requiresBody = method !== "HEAD" && method !== "GET";
|
|
40
|
+
if (autoPreflight && method === "OPTIONS") {
|
|
41
|
+
res.writeStatus("204 No Content");
|
|
42
|
+
let hasPoweredByHeader = false;
|
|
43
|
+
if (normalizedStaticHeaders?.length) {
|
|
44
|
+
for (let i = 0; i < normalizedStaticHeaders.length; i++) {
|
|
45
|
+
const [key, value] = normalizedStaticHeaders[i];
|
|
46
|
+
if (key === "content-length" || key === "transfer-encoding") {
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
if (key === "x-powered-by") {
|
|
50
|
+
hasPoweredByHeader = true;
|
|
51
|
+
}
|
|
52
|
+
res.writeHeader(key, value);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
if (poweredByHeader && !hasPoweredByHeader) {
|
|
56
|
+
res.writeHeader("x-powered-by", "Oweb");
|
|
57
|
+
}
|
|
58
|
+
res.end();
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
36
61
|
res.finished = false;
|
|
37
62
|
res.aborted = false;
|
|
38
63
|
if (requiresBody) {
|
|
@@ -47,7 +72,7 @@ async function server_default({ cert_file_name, key_file_name }) {
|
|
|
47
72
|
query,
|
|
48
73
|
url
|
|
49
74
|
});
|
|
50
|
-
const resWrapper = new HttpResponse(res, uServer);
|
|
75
|
+
const resWrapper = new HttpResponse(res, uServer, normalizedStaticHeaders);
|
|
51
76
|
reqWrapper.res = resWrapper;
|
|
52
77
|
resWrapper.req = reqWrapper;
|
|
53
78
|
reqWrapper.bindSocketFactory(() => resWrapper.socket);
|
package/package.json
CHANGED
package/0http.js
DELETED
package/allahbeler2.png
DELETED
|
Binary file
|
package/allahbeyler.png
DELETED
|
Binary file
|
package/avatar.png
DELETED
|
Binary file
|
package/benchmark.txt
DELETED
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
OWEB UWS:
|
|
2
|
-
|
|
3
|
-
╰─ autocannon -c 100 -d 40 -p 10 localhost:3000
|
|
4
|
-
Running 40s test @ http://localhost:3000
|
|
5
|
-
100 connections with 10 pipelining factor
|
|
6
|
-
|
|
7
|
-
running [=================== ] 95%
|
|
8
|
-
┌─────────┬──────┬───────┬───────┬───────┬──────────┬──────────┬────────┐
|
|
9
|
-
│ Stat │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │
|
|
10
|
-
├─────────┼──────┼───────┼───────┼───────┼──────────┼──────────┼────────┤
|
|
11
|
-
│ Latency │ 5 ms │ 12 ms │ 73 ms │ 98 ms │ 15.81 ms │ 15.73 ms │ 158 ms │
|
|
12
|
-
└─────────┴──────┴───────┴───────┴───────┴──────────┴──────────┴────────┘
|
|
13
|
-
┌───────────┬─────────┬─────────┬─────────┬─────────┬───────────┬──────────┬─────────┐
|
|
14
|
-
│ Stat │ 1% │ 2.5% │ 50% │ 97.5% │ Avg │ Stdev │ Min │
|
|
15
|
-
├───────────┼─────────┼─────────┼─────────┼─────────┼───────────┼──────────┼─────────┤
|
|
16
|
-
│ Req/Sec │ 57.087 │ 57.087 │ 64.991 │ 72.191 │ 64.785,27 │ 3.607,71 │ 57.060 │
|
|
17
|
-
├───────────┼─────────┼─────────┼─────────┼─────────┼───────────┼──────────┼─────────┤
|
|
18
|
-
│ Bytes/Sec │ 9.42 MB │ 9.42 MB │ 10.7 MB │ 11.9 MB │ 10.7 MB │ 596 kB │ 9.41 MB │
|
|
19
|
-
└───────────┴─────────┴─────────┴─────────┴─────────┴───────────┴──────────┴─────────┘
|
|
20
|
-
|
|
21
|
-
Req/Bytes counts sampled once per second.
|
|
22
|
-
# of samples: 38
|
|
23
|
-
|
|
24
|
-
2463k requests in 40.19s, 406 MB read
|
|
25
|
-
╭─ pwsh 40s 459ms⠀ 6,13:14
|
|
26
|
-
╰─ autocannon -c 100 -d 40 -p 10 localhost:3000
|
|
27
|
-
Running 40s test @ http://localhost:3000
|
|
28
|
-
100 connections with 10 pipelining factor
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
┌─────────┬──────┬───────┬───────┬───────┬─────────┬──────────┬────────┐
|
|
32
|
-
│ Stat │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │
|
|
33
|
-
├─────────┼──────┼───────┼───────┼───────┼─────────┼──────────┼────────┤
|
|
34
|
-
│ Latency │ 5 ms │ 13 ms │ 72 ms │ 98 ms │ 15.9 ms │ 15.27 ms │ 262 ms │
|
|
35
|
-
└─────────┴──────┴───────┴───────┴───────┴─────────┴──────────┴────────┘
|
|
36
|
-
┌───────────┬─────────┬─────────┬─────────┬─────────┬───────────┬──────────┬─────────┐
|
|
37
|
-
│ Stat │ 1% │ 2.5% │ 50% │ 97.5% │ Avg │ Stdev │ Min │
|
|
38
|
-
├───────────┼─────────┼─────────┼─────────┼─────────┼───────────┼──────────┼─────────┤
|
|
39
|
-
│ Req/Sec │ 48.959 │ 48.959 │ 64.447 │ 70.783 │ 63.949,54 │ 4.776,67 │ 48.930 │
|
|
40
|
-
├───────────┼─────────┼─────────┼─────────┼─────────┼───────────┼──────────┼─────────┤
|
|
41
|
-
│ Bytes/Sec │ 8.08 MB │ 8.08 MB │ 10.6 MB │ 11.7 MB │ 10.6 MB │ 789 kB │ 8.07 MB │
|
|
42
|
-
└───────────┴─────────┴─────────┴─────────┴─────────┴───────────┴──────────┴─────────┘
|
|
43
|
-
|
|
44
|
-
Req/Bytes counts sampled once per second.
|
|
45
|
-
# of samples: 39
|
|
46
|
-
|
|
47
|
-
2495k requests in 40.96s, 412 MB read
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
OWEB FASTIFY:
|
|
51
|
-
|
|
52
|
-
╰─ autocannon -c 100 -d 40 -p 10 localhost:3000
|
|
53
|
-
Running 40s test @ http://localhost:3000
|
|
54
|
-
100 connections with 10 pipelining factor
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
┌─────────┬──────┬───────┬───────┬────────┬──────────┬──────────┬────────┐
|
|
58
|
-
│ Stat │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │
|
|
59
|
-
├─────────┼──────┼───────┼───────┼────────┼──────────┼──────────┼────────┤
|
|
60
|
-
│ Latency │ 3 ms │ 21 ms │ 84 ms │ 110 ms │ 26.12 ms │ 20.65 ms │ 200 ms │
|
|
61
|
-
└─────────┴──────┴───────┴───────┴────────┴──────────┴──────────┴────────┘
|
|
62
|
-
┌───────────┬─────────┬─────────┬─────────┬────────┬──────────┬──────────┬─────────┐
|
|
63
|
-
│ Stat │ 1% │ 2.5% │ 50% │ 97.5% │ Avg │ Stdev │ Min │
|
|
64
|
-
├───────────┼─────────┼─────────┼─────────┼────────┼──────────┼──────────┼─────────┤
|
|
65
|
-
│ Req/Sec │ 26.751 │ 26.751 │ 36.287 │ 45.503 │ 37.570,6 │ 4.606,09 │ 26.741 │
|
|
66
|
-
├───────────┼─────────┼─────────┼─────────┼────────┼──────────┼──────────┼─────────┤
|
|
67
|
-
│ Bytes/Sec │ 4.76 MB │ 4.76 MB │ 6.46 MB │ 8.1 MB │ 6.69 MB │ 820 kB │ 4.76 MB │
|
|
68
|
-
└───────────┴─────────┴─────────┴─────────┴────────┴──────────┴──────────┴─────────┘
|
|
69
|
-
|
|
70
|
-
Req/Bytes counts sampled once per second.
|
|
71
|
-
# of samples: 40
|
|
72
|
-
|
|
73
|
-
1504k requests in 40.05s, 268 MB read
|
|
74
|
-
╭─ pwsh 40s 334ms⠀ 6,13:16
|
|
75
|
-
╰─ autocannon -c 100 -d 40 -p 10 localhost:3000
|
|
76
|
-
Running 40s test @ http://localhost:3000
|
|
77
|
-
100 connections with 10 pipelining factor
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
┌─────────┬──────┬───────┬───────┬────────┬──────────┬──────────┬────────┐
|
|
81
|
-
│ Stat │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │
|
|
82
|
-
├─────────┼──────┼───────┼───────┼────────┼──────────┼──────────┼────────┤
|
|
83
|
-
│ Latency │ 4 ms │ 20 ms │ 93 ms │ 122 ms │ 24.03 ms │ 21.64 ms │ 209 ms │
|
|
84
|
-
└─────────┴──────┴───────┴───────┴────────┴──────────┴──────────┴────────┘
|
|
85
|
-
┌───────────┬────────┬────────┬─────────┬─────────┬───────────┬──────────┬────────┐
|
|
86
|
-
│ Stat │ 1% │ 2.5% │ 50% │ 97.5% │ Avg │ Stdev │ Min │
|
|
87
|
-
├───────────┼────────┼────────┼─────────┼─────────┼───────────┼──────────┼────────┤
|
|
88
|
-
│ Req/Sec │ 29.759 │ 29.759 │ 41.343 │ 44.895 │ 40.765,81 │ 3.004,68 │ 29.750 │
|
|
89
|
-
├───────────┼────────┼────────┼─────────┼─────────┼───────────┼──────────┼────────┤
|
|
90
|
-
│ Bytes/Sec │ 5.3 MB │ 5.3 MB │ 7.36 MB │ 7.99 MB │ 7.26 MB │ 535 kB │ 5.3 MB │
|
|
91
|
-
└───────────┴────────┴────────┴─────────┴─────────┴───────────┴──────────┴────────┘
|
|
92
|
-
|
|
93
|
-
Req/Bytes counts sampled once per second.
|
|
94
|
-
# of samples: 40
|
|
95
|
-
|
|
96
|
-
1632k requests in 40.05s, 290 MB read
|
|
97
|
-
|
|
98
|
-
DÜZ FASTIFY:
|
|
99
|
-
|
|
100
|
-
Running 40s test @ http://localhost:3000
|
|
101
|
-
100 connections with 10 pipelining factor
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
┌─────────┬──────┬───────┬───────┬───────┬──────────┬──────────┬────────┐
|
|
105
|
-
│ Stat │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │
|
|
106
|
-
├─────────┼──────┼───────┼───────┼───────┼──────────┼──────────┼────────┤
|
|
107
|
-
│ Latency │ 3 ms │ 18 ms │ 76 ms │ 97 ms │ 21.09 ms │ 17.82 ms │ 257 ms │
|
|
108
|
-
└─────────┴──────┴───────┴───────┴───────┴──────────┴──────────┴────────┘
|
|
109
|
-
┌───────────┬─────────┬─────────┬─────────┬─────────┬──────────┬──────────┬─────────┐
|
|
110
|
-
│ Stat │ 1% │ 2.5% │ 50% │ 97.5% │ Avg │ Stdev │ Min │
|
|
111
|
-
├───────────┼─────────┼─────────┼─────────┼─────────┼──────────┼──────────┼─────────┤
|
|
112
|
-
│ Req/Sec │ 32.543 │ 32.543 │ 46.783 │ 49.695 │ 46.349,8 │ 2.964,89 │ 32.530 │
|
|
113
|
-
├───────────┼─────────┼─────────┼─────────┼─────────┼──────────┼──────────┼─────────┤
|
|
114
|
-
│ Bytes/Sec │ 5.79 MB │ 5.79 MB │ 8.33 MB │ 8.85 MB │ 8.25 MB │ 528 kB │ 5.79 MB │
|
|
115
|
-
└───────────┴─────────┴─────────┴─────────┴─────────┴──────────┴──────────┴─────────┘
|
|
116
|
-
|
|
117
|
-
Req/Bytes counts sampled once per second.
|
|
118
|
-
# of samples: 40
|
|
119
|
-
|
|
120
|
-
1855k requests in 40.06s, 330 MB read
|
|
121
|
-
╭─ pwsh 40s 362ms⠀ 6,13:18
|
|
122
|
-
╰─ autocannon -c 100 -d 40 -p 10 localhost:3000
|
|
123
|
-
Running 40s test @ http://localhost:3000
|
|
124
|
-
100 connections with 10 pipelining factor
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
┌─────────┬──────┬───────┬───────┬────────┬──────────┬─────────┬────────┐
|
|
128
|
-
│ Stat │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │
|
|
129
|
-
├─────────┼──────┼───────┼───────┼────────┼──────────┼─────────┼────────┤
|
|
130
|
-
│ Latency │ 3 ms │ 18 ms │ 80 ms │ 102 ms │ 21.48 ms │ 18.3 ms │ 188 ms │
|
|
131
|
-
└─────────┴──────┴───────┴───────┴────────┴──────────┴─────────┴────────┘
|
|
132
|
-
┌───────────┬─────────┬─────────┬─────────┬────────┬──────────┬──────────┬─────────┐
|
|
133
|
-
│ Stat │ 1% │ 2.5% │ 50% │ 97.5% │ Avg │ Stdev │ Min │
|
|
134
|
-
├───────────┼─────────┼─────────┼─────────┼────────┼──────────┼──────────┼─────────┤
|
|
135
|
-
│ Req/Sec │ 37.567 │ 37.567 │ 45.535 │ 48.863 │ 45.501,6 │ 2.214,24 │ 37.550 │
|
|
136
|
-
├───────────┼─────────┼─────────┼─────────┼────────┼──────────┼──────────┼─────────┤
|
|
137
|
-
│ Bytes/Sec │ 6.68 MB │ 6.68 MB │ 8.11 MB │ 8.7 MB │ 8.1 MB │ 394 kB │ 6.68 MB │
|
|
138
|
-
└───────────┴─────────┴─────────┴─────────┴────────┴──────────┴──────────┴─────────┘
|
|
139
|
-
|
|
140
|
-
Req/Bytes counts sampled once per second.
|
|
141
|
-
# of samples: 40
|
|
142
|
-
|
|
143
|
-
1821k requests in 40.05s, 324 MB read
|
|
144
|
-
|
|
145
|
-
DÜZ UWS:
|
|
146
|
-
|
|
147
|
-
Running 40s test @ http://localhost:3000
|
|
148
|
-
100 connections with 10 pipelining factor
|
|
149
|
-
|
|
150
|
-
running [=================== ] 95%
|
|
151
|
-
┌─────────┬───────┬───────┬───────┬───────┬──────────┬─────────┬────────┐
|
|
152
|
-
│ Stat │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │
|
|
153
|
-
├─────────┼───────┼───────┼───────┼───────┼──────────┼─────────┼────────┤
|
|
154
|
-
│ Latency │ 11 ms │ 12 ms │ 19 ms │ 22 ms │ 12.93 ms │ 3.39 ms │ 167 ms │
|
|
155
|
-
└─────────┴───────┴───────┴───────┴───────┴──────────┴─────────┴────────┘
|
|
156
|
-
┌───────────┬─────────┬─────────┬─────────┬─────────┬───────────┬─────────┬─────────┐
|
|
157
|
-
│ Stat │ 1% │ 2.5% │ 50% │ 97.5% │ Avg │ Stdev │ Min │
|
|
158
|
-
├───────────┼─────────┼─────────┼─────────┼─────────┼───────────┼─────────┼─────────┤
|
|
159
|
-
│ Req/Sec │ 71.743 │ 71.743 │ 80.831 │ 80.959 │ 79.149,48 │ 3.427,1 │ 71.730 │
|
|
160
|
-
├───────────┼─────────┼─────────┼─────────┼─────────┼───────────┼─────────┼─────────┤
|
|
161
|
-
│ Bytes/Sec │ 10.6 MB │ 10.6 MB │ 11.9 MB │ 11.9 MB │ 11.6 MB │ 503 kB │ 10.5 MB │
|
|
162
|
-
└───────────┴─────────┴─────────┴─────────┴─────────┴───────────┴─────────┴─────────┘
|
|
163
|
-
|
|
164
|
-
Req/Bytes counts sampled once per second.
|
|
165
|
-
# of samples: 38
|
|
166
|
-
|
|
167
|
-
3009k requests in 40.43s, 442 MB read
|
|
168
|
-
╭─ pwsh 40s 739ms⠀ 6,13:20
|
|
169
|
-
╰─ autocannon -c 100 -d 40 -p 10 localhost:3000
|
|
170
|
-
Running 40s test @ http://localhost:3000
|
|
171
|
-
100 connections with 10 pipelining factor
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
┌─────────┬───────┬───────┬───────┬───────┬──────────┬─────────┬────────┐
|
|
175
|
-
│ Stat │ 2.5% │ 50% │ 97.5% │ 99% │ Avg │ Stdev │ Max │
|
|
176
|
-
├─────────┼───────┼───────┼───────┼───────┼──────────┼─────────┼────────┤
|
|
177
|
-
│ Latency │ 10 ms │ 12 ms │ 20 ms │ 22 ms │ 12.44 ms │ 3.35 ms │ 181 ms │
|
|
178
|
-
└─────────┴───────┴───────┴───────┴───────┴──────────┴─────────┴────────┘
|
|
179
|
-
┌───────────┬────────┬────────┬─────────┬─────────┬───────────┬──────────┬────────┐
|
|
180
|
-
│ Stat │ 1% │ 2.5% │ 50% │ 97.5% │ Avg │ Stdev │ Min │
|
|
181
|
-
├───────────┼────────┼────────┼─────────┼─────────┼───────────┼──────────┼────────┤
|
|
182
|
-
│ Req/Sec │ 68.287 │ 68.287 │ 80.831 │ 89.855 │ 81.377,65 │ 4.922,97 │ 68.284 │
|
|
183
|
-
├───────────┼────────┼────────┼─────────┼─────────┼───────────┼──────────┼────────┤
|
|
184
|
-
│ Bytes/Sec │ 10 MB │ 10 MB │ 11.9 MB │ 13.2 MB │ 12 MB │ 724 kB │ 10 MB │
|
|
185
|
-
└───────────┴────────┴────────┴─────────┴─────────┴───────────┴──────────┴────────┘
|
|
186
|
-
|
|
187
|
-
Req/Bytes counts sampled once per second.
|
|
188
|
-
# of samples: 39
|
|
189
|
-
|
|
190
|
-
3175k requests in 41.09s, 467 MB read
|
|
191
|
-
|
package/express.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import express from 'express';
|
|
2
|
-
|
|
3
|
-
const app = express();
|
|
4
|
-
const port = 3000;
|
|
5
|
-
|
|
6
|
-
// Define a route for the root URL
|
|
7
|
-
app.get('/', (req, res) => {
|
|
8
|
-
res.send('Hello World from Express!');
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
// Start the server
|
|
12
|
-
app.listen(port, () => {
|
|
13
|
-
console.log(`Express app listening at http://localhost:${port}`);
|
|
14
|
-
});
|
package/fasti.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import fastify from 'fastify';
|
|
2
|
-
|
|
3
|
-
const app = fastify();
|
|
4
|
-
|
|
5
|
-
app.get('/', async (request, reply) => {
|
|
6
|
-
return 'Hello, World!';
|
|
7
|
-
});
|
|
8
|
-
|
|
9
|
-
app.listen({ port: 3000, host: '0.0.0.0' }, (err) => {
|
|
10
|
-
if (err) {
|
|
11
|
-
console.error(err);
|
|
12
|
-
process.exit(1);
|
|
13
|
-
}
|
|
14
|
-
});
|
package/purehttp.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import http from 'node:http';
|
|
2
|
-
|
|
3
|
-
const hostname = '127.0.0.1';
|
|
4
|
-
const port = 3000;
|
|
5
|
-
|
|
6
|
-
// Create the server instance
|
|
7
|
-
const server = http.createServer((req, res) => {
|
|
8
|
-
// Set the response header with HTTP status and Content-Type
|
|
9
|
-
res.statusCode = 200;
|
|
10
|
-
res.setHeader('Content-Type', 'text/plain');
|
|
11
|
-
|
|
12
|
-
// Send the response body
|
|
13
|
-
res.end('Hello, World!\n');
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
// Start listening for requests
|
|
17
|
-
server.listen(port, hostname, () => {
|
|
18
|
-
console.log(`Server running at http://${hostname}:${port}/`);
|
|
19
|
-
});
|
package/uws.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import uWS from 'uwebsockets.js';
|
|
2
|
-
|
|
3
|
-
uWS.App()
|
|
4
|
-
.get('/', (res, req) => {
|
|
5
|
-
res.writeStatus('200 OK')
|
|
6
|
-
.writeHeader('Content-Type', 'text/plain; charset=utf-8')
|
|
7
|
-
.end('Hello, World!');
|
|
8
|
-
})
|
|
9
|
-
.listen('0.0.0.0', 3000, (listenSocket) => {
|
|
10
|
-
if (listenSocket) {
|
|
11
|
-
console.log('uWebSockets.js listening on http://localhost:3000');
|
|
12
|
-
} else {
|
|
13
|
-
console.error('Failed to listen on port 3000');
|
|
14
|
-
process.exit(1);
|
|
15
|
-
}
|
|
16
|
-
});
|