owebjs 1.5.4-dev → 1.5.7-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/0http.js +8 -0
- package/README.md +434 -270
- package/benchmark.txt +191 -0
- package/dist/index.d.ts +3 -0
- package/dist/structures/Oweb.js +52 -7
- package/dist/utils/assignRoutes.js +298 -173
- package/dist/utils/walk.js +5 -6
- package/dist/utils/watcher.js +21 -9
- package/dist/uwebsocket/request.js +59 -26
- package/dist/uwebsocket/response.js +21 -10
- package/dist/uwebsocket/responseSocket.js +5 -1
- package/dist/uwebsocket/server.js +81 -51
- package/express.js +14 -0
- package/fasti.js +14 -0
- package/package.json +6 -4
- package/purehttp.js +19 -0
- package/uws.js +16 -0
package/dist/utils/watcher.js
CHANGED
|
@@ -19,20 +19,32 @@ function watchDirectory(dir, ignoreInitial = true, onUpdate) {
|
|
|
19
19
|
".js",
|
|
20
20
|
".ts"
|
|
21
21
|
];
|
|
22
|
-
|
|
22
|
+
let operationQueue = Promise.resolve();
|
|
23
|
+
const enqueueUpdate = /* @__PURE__ */ __name((op, filePath) => {
|
|
23
24
|
if (!supportedExtensions.includes(extname(filePath))) return;
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
operationQueue = operationQueue.then(() => {
|
|
26
|
+
let content = "";
|
|
27
|
+
if (op !== "delete-file") {
|
|
28
|
+
try {
|
|
29
|
+
content = readFileSync(filePath, "utf-8");
|
|
30
|
+
} catch {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
return onUpdate(op, filePath, content);
|
|
35
|
+
}).catch(() => {
|
|
36
|
+
});
|
|
37
|
+
}, "enqueueUpdate");
|
|
38
|
+
watcher.on("add", (filePath) => {
|
|
39
|
+
enqueueUpdate("new-file", filePath);
|
|
26
40
|
});
|
|
27
|
-
watcher.on("change",
|
|
28
|
-
|
|
29
|
-
const content = readFileSync(filePath, "utf-8");
|
|
30
|
-
onUpdate("modify-file", filePath, content);
|
|
41
|
+
watcher.on("change", (filePath) => {
|
|
42
|
+
enqueueUpdate("modify-file", filePath);
|
|
31
43
|
});
|
|
32
44
|
watcher.on("unlink", (filePath) => {
|
|
33
|
-
|
|
34
|
-
onUpdate("delete-file", filePath, "");
|
|
45
|
+
enqueueUpdate("delete-file", filePath);
|
|
35
46
|
});
|
|
47
|
+
return watcher;
|
|
36
48
|
}
|
|
37
49
|
__name(watchDirectory, "watchDirectory");
|
|
38
50
|
export {
|
|
@@ -3,6 +3,14 @@ import {
|
|
|
3
3
|
} from "../chunk-SHUYVCID.js";
|
|
4
4
|
import { Readable } from "stream";
|
|
5
5
|
import { forEach } from './utils/object.js';
|
|
6
|
+
const NOOP_SOCKET = Object.freeze({
|
|
7
|
+
destroy: /* @__PURE__ */ __name(() => {
|
|
8
|
+
}, "destroy"),
|
|
9
|
+
on: /* @__PURE__ */ __name(() => {
|
|
10
|
+
}, "on"),
|
|
11
|
+
removeListener: /* @__PURE__ */ __name(() => {
|
|
12
|
+
}, "removeListener")
|
|
13
|
+
});
|
|
6
14
|
class HttpRequest extends Readable {
|
|
7
15
|
static {
|
|
8
16
|
__name(this, "HttpRequest");
|
|
@@ -15,34 +23,55 @@ class HttpRequest extends Readable {
|
|
|
15
23
|
statusCode;
|
|
16
24
|
statusMessage;
|
|
17
25
|
body;
|
|
18
|
-
headers;
|
|
19
|
-
socket;
|
|
20
26
|
// https://nodejs.org/api/http.html#class-httpincomingmessage
|
|
21
27
|
complete = false;
|
|
22
28
|
connection;
|
|
23
|
-
|
|
29
|
+
resumeScheduled = false;
|
|
30
|
+
_headers = null;
|
|
31
|
+
_socket = NOOP_SOCKET;
|
|
32
|
+
_socketFactory;
|
|
33
|
+
get socket() {
|
|
34
|
+
if (this._socketFactory && this._socket === NOOP_SOCKET) {
|
|
35
|
+
this._socket = this._socketFactory();
|
|
36
|
+
this.connection = this._socket;
|
|
37
|
+
}
|
|
38
|
+
return this._socket;
|
|
39
|
+
}
|
|
40
|
+
set socket(value) {
|
|
41
|
+
this._socket = value || NOOP_SOCKET;
|
|
42
|
+
this.connection = this._socket;
|
|
43
|
+
this._socketFactory = void 0;
|
|
44
|
+
}
|
|
45
|
+
bindSocketFactory(factory) {
|
|
46
|
+
this._socketFactory = factory;
|
|
47
|
+
this._socket = NOOP_SOCKET;
|
|
48
|
+
this.connection = this._socket;
|
|
49
|
+
}
|
|
50
|
+
get headers() {
|
|
51
|
+
if (!this._headers) {
|
|
52
|
+
const headers = {};
|
|
53
|
+
this.req.forEach((header, value) => {
|
|
54
|
+
headers[header.toLowerCase()] = value;
|
|
55
|
+
});
|
|
56
|
+
this._headers = headers;
|
|
57
|
+
}
|
|
58
|
+
return this._headers;
|
|
59
|
+
}
|
|
60
|
+
set headers(value) {
|
|
61
|
+
this._headers = value;
|
|
62
|
+
}
|
|
63
|
+
constructor(uRequest, uResponse, prefetched) {
|
|
24
64
|
super({
|
|
25
65
|
highWaterMark: 64 * 1024
|
|
26
66
|
});
|
|
27
67
|
this.uResponse = uResponse;
|
|
28
68
|
this.req = uRequest;
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
this.
|
|
69
|
+
const query = prefetched?.query ?? uRequest.getQuery();
|
|
70
|
+
const url = prefetched?.url ?? uRequest.getUrl();
|
|
71
|
+
this.url = url + (query ? "?" + query : "");
|
|
72
|
+
this.method = prefetched?.method ?? uRequest.getMethod().toUpperCase();
|
|
32
73
|
this.body = {};
|
|
33
|
-
this.
|
|
34
|
-
this.socket = {
|
|
35
|
-
destroy: /* @__PURE__ */ __name(() => {
|
|
36
|
-
}, "destroy"),
|
|
37
|
-
on: /* @__PURE__ */ __name(() => {
|
|
38
|
-
}, "on"),
|
|
39
|
-
removeListener: /* @__PURE__ */ __name(() => {
|
|
40
|
-
}, "removeListener")
|
|
41
|
-
};
|
|
42
|
-
this.connection = this.socket;
|
|
43
|
-
uRequest.forEach((header, value) => {
|
|
44
|
-
this.headers[header.toLowerCase()] = value;
|
|
45
|
-
});
|
|
74
|
+
this.connection = this._socket;
|
|
46
75
|
}
|
|
47
76
|
getRawHeaders() {
|
|
48
77
|
const raw = [];
|
|
@@ -55,13 +84,17 @@ class HttpRequest extends Readable {
|
|
|
55
84
|
return this.req;
|
|
56
85
|
}
|
|
57
86
|
_read(_) {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
87
|
+
const uRes = this.uResponse;
|
|
88
|
+
if (!uRes || uRes.aborted || uRes.finished || !uRes.isPaused) return;
|
|
89
|
+
if (this.resumeScheduled) return;
|
|
90
|
+
this.resumeScheduled = true;
|
|
91
|
+
setImmediate(() => {
|
|
92
|
+
this.resumeScheduled = false;
|
|
93
|
+
const res = this.uResponse;
|
|
94
|
+
if (res && !res.aborted && !res.finished && res.isPaused) {
|
|
95
|
+
res.resume();
|
|
96
|
+
}
|
|
97
|
+
});
|
|
65
98
|
}
|
|
66
99
|
}
|
|
67
100
|
export {
|
|
@@ -16,8 +16,8 @@ class HttpResponse extends Writable {
|
|
|
16
16
|
statusMessage;
|
|
17
17
|
__headers;
|
|
18
18
|
headersSent;
|
|
19
|
-
socket;
|
|
20
19
|
finished;
|
|
20
|
+
_socket = null;
|
|
21
21
|
constructor(uResponse, uServer) {
|
|
22
22
|
super();
|
|
23
23
|
this.res = uResponse;
|
|
@@ -26,10 +26,19 @@ class HttpResponse extends Writable {
|
|
|
26
26
|
this.statusMessage = null;
|
|
27
27
|
this.__headers = {};
|
|
28
28
|
this.headersSent = false;
|
|
29
|
-
this.
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
29
|
+
this.finished = false;
|
|
30
|
+
}
|
|
31
|
+
get socket() {
|
|
32
|
+
if (!this._socket) {
|
|
33
|
+
this._socket = new HttpResponseSocket(this.res);
|
|
34
|
+
}
|
|
35
|
+
return this._socket;
|
|
36
|
+
}
|
|
37
|
+
isClosed() {
|
|
38
|
+
return this.finished || this.res.aborted || this.res.finished;
|
|
39
|
+
}
|
|
40
|
+
get sent() {
|
|
41
|
+
return this.isClosed();
|
|
33
42
|
}
|
|
34
43
|
setHeader(name, value) {
|
|
35
44
|
this.__headers[toLowerCase(name)] = value;
|
|
@@ -50,7 +59,7 @@ class HttpResponse extends Writable {
|
|
|
50
59
|
delete this.__headers[toLowerCase(name)];
|
|
51
60
|
}
|
|
52
61
|
_flushHeaders() {
|
|
53
|
-
if (this.headersSent) return;
|
|
62
|
+
if (this.headersSent || this.isClosed()) return;
|
|
54
63
|
const message = this.statusMessage || http.STATUS_CODES[this.statusCode] || "Unknown";
|
|
55
64
|
this.res.writeStatus(`${this.statusCode} ${message}`);
|
|
56
65
|
const keys = Object.keys(this.__headers);
|
|
@@ -72,14 +81,16 @@ class HttpResponse extends Writable {
|
|
|
72
81
|
}
|
|
73
82
|
//@ts-ignore
|
|
74
83
|
write(data) {
|
|
75
|
-
if (this.
|
|
84
|
+
if (this.isClosed()) return;
|
|
76
85
|
this.res.cork(() => {
|
|
77
86
|
this._flushHeaders();
|
|
78
|
-
this.
|
|
87
|
+
if (!this.isClosed()) {
|
|
88
|
+
this.res.write(data);
|
|
89
|
+
}
|
|
79
90
|
});
|
|
80
91
|
}
|
|
81
92
|
writeHead(statusCode) {
|
|
82
|
-
if (this.
|
|
93
|
+
if (this.isClosed()) return;
|
|
83
94
|
this.statusCode = statusCode;
|
|
84
95
|
let headers;
|
|
85
96
|
if (arguments.length === 2) {
|
|
@@ -96,7 +107,7 @@ class HttpResponse extends Writable {
|
|
|
96
107
|
}
|
|
97
108
|
//@ts-ignore
|
|
98
109
|
end(data) {
|
|
99
|
-
if (this.
|
|
110
|
+
if (this.isClosed()) return;
|
|
100
111
|
this.res.cork(() => {
|
|
101
112
|
this._flushHeaders();
|
|
102
113
|
this.finished = true;
|
|
@@ -6,11 +6,15 @@ class HttpResponseSocket {
|
|
|
6
6
|
__name(this, "HttpResponseSocket");
|
|
7
7
|
}
|
|
8
8
|
uResponse;
|
|
9
|
+
_remoteAddress;
|
|
9
10
|
constructor(uResponse) {
|
|
10
11
|
this.uResponse = uResponse;
|
|
11
12
|
}
|
|
12
13
|
get remoteAddress() {
|
|
13
|
-
|
|
14
|
+
if (this._remoteAddress === void 0) {
|
|
15
|
+
this._remoteAddress = Buffer.from(this.uResponse.getRemoteAddressAsText()).toString();
|
|
16
|
+
}
|
|
17
|
+
return this._remoteAddress;
|
|
14
18
|
}
|
|
15
19
|
destroy() {
|
|
16
20
|
return this.uResponse.end();
|
|
@@ -22,41 +22,56 @@ async function server_default({ cert_file_name, key_file_name }) {
|
|
|
22
22
|
cert_file_name,
|
|
23
23
|
key_file_name
|
|
24
24
|
};
|
|
25
|
+
const copyArrayBufferToBuffer = /* @__PURE__ */ __name((bytes) => {
|
|
26
|
+
const src = new Uint8Array(bytes);
|
|
27
|
+
const out = Buffer.allocUnsafe(src.byteLength);
|
|
28
|
+
out.set(src);
|
|
29
|
+
return out;
|
|
30
|
+
}, "copyArrayBufferToBuffer");
|
|
25
31
|
const uServer = uWS[appType](config).any("/*", (res, req) => {
|
|
32
|
+
const method = req.getMethod().toUpperCase();
|
|
33
|
+
const query = req.getQuery();
|
|
34
|
+
const url = req.getUrl();
|
|
35
|
+
const requiresBody = method !== "HEAD" && method !== "GET";
|
|
26
36
|
res.finished = false;
|
|
27
37
|
res.aborted = false;
|
|
28
|
-
|
|
38
|
+
if (requiresBody) {
|
|
39
|
+
res.isPaused = false;
|
|
40
|
+
}
|
|
29
41
|
res.onAborted(() => {
|
|
30
42
|
res.aborted = true;
|
|
31
43
|
res.finished = true;
|
|
32
44
|
});
|
|
33
|
-
const reqWrapper = new HttpRequest(req, res
|
|
45
|
+
const reqWrapper = new HttpRequest(req, res, {
|
|
46
|
+
method,
|
|
47
|
+
query,
|
|
48
|
+
url
|
|
49
|
+
});
|
|
34
50
|
const resWrapper = new HttpResponse(res, uServer);
|
|
35
51
|
reqWrapper.res = resWrapper;
|
|
36
52
|
resWrapper.req = reqWrapper;
|
|
37
|
-
reqWrapper.
|
|
38
|
-
const originalResume = res.resume;
|
|
39
|
-
res.resume = function() {
|
|
40
|
-
if (res.isPaused && !res.finished && !res.aborted) {
|
|
41
|
-
res.isPaused = false;
|
|
42
|
-
originalResume.call(res);
|
|
43
|
-
}
|
|
44
|
-
};
|
|
53
|
+
reqWrapper.bindSocketFactory(() => resWrapper.socket);
|
|
45
54
|
handler(reqWrapper, resWrapper);
|
|
46
|
-
|
|
47
|
-
|
|
55
|
+
if (requiresBody && !resWrapper.finished) {
|
|
56
|
+
const originalResume = res.resume;
|
|
57
|
+
res.resume = function() {
|
|
58
|
+
if (res.isPaused && !res.finished && !res.aborted) {
|
|
59
|
+
res.isPaused = false;
|
|
60
|
+
originalResume.call(res);
|
|
61
|
+
}
|
|
62
|
+
};
|
|
48
63
|
res.onData((bytes, isLast) => {
|
|
49
|
-
if (res.finished || res.aborted) return;
|
|
50
|
-
const chunk =
|
|
64
|
+
if (res.finished || res.aborted || reqWrapper.destroyed) return;
|
|
65
|
+
const chunk = copyArrayBufferToBuffer(bytes);
|
|
51
66
|
const streamReady = reqWrapper.push(chunk);
|
|
52
67
|
if (isLast) {
|
|
53
68
|
reqWrapper.complete = true;
|
|
54
69
|
reqWrapper.push(null);
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
if (!streamReady && !res.isPaused) {
|
|
73
|
+
res.isPaused = true;
|
|
74
|
+
res.pause();
|
|
60
75
|
}
|
|
61
76
|
});
|
|
62
77
|
} else if (!resWrapper.finished) {
|
|
@@ -185,6 +200,9 @@ async function server_default({ cert_file_name, key_file_name }) {
|
|
|
185
200
|
statusCode: 200,
|
|
186
201
|
_headers: {},
|
|
187
202
|
finished: false,
|
|
203
|
+
get sent() {
|
|
204
|
+
return this.finished;
|
|
205
|
+
},
|
|
188
206
|
header(key, value) {
|
|
189
207
|
this._headers[key.toLowerCase()] = value;
|
|
190
208
|
return this;
|
|
@@ -205,40 +223,52 @@ async function server_default({ cert_file_name, key_file_name }) {
|
|
|
205
223
|
return this;
|
|
206
224
|
}
|
|
207
225
|
};
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
226
|
+
const sendUpgradeError = /* @__PURE__ */ __name((hookError) => {
|
|
227
|
+
if (aborted || resWrapper.finished) return;
|
|
228
|
+
const normalizedError = hookError instanceof Error ? hookError : new Error(String(hookError));
|
|
229
|
+
console.error("WebSocket Hook Error:", normalizedError);
|
|
230
|
+
res.writeStatus("500 Internal Server Error");
|
|
231
|
+
res.end(JSON.stringify({
|
|
232
|
+
error: "Internal Server Error",
|
|
233
|
+
message: normalizedError.message
|
|
234
|
+
}));
|
|
235
|
+
}, "sendUpgradeError");
|
|
236
|
+
const finishUpgrade = /* @__PURE__ */ __name(() => {
|
|
237
|
+
if (aborted || resWrapper.finished) return;
|
|
238
|
+
const reqData = {
|
|
239
|
+
...reqWrapper,
|
|
240
|
+
query
|
|
241
|
+
};
|
|
242
|
+
res.upgrade({
|
|
243
|
+
req: reqData
|
|
244
|
+
}, secKey, secProtocol, secExtensions, context);
|
|
245
|
+
}, "finishUpgrade");
|
|
246
|
+
let hookIndex = 0;
|
|
247
|
+
const runNextHook = /* @__PURE__ */ __name((hookError) => {
|
|
248
|
+
if (hookError) {
|
|
249
|
+
sendUpgradeError(hookError);
|
|
250
|
+
return;
|
|
222
251
|
}
|
|
223
|
-
|
|
224
|
-
if (
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
res.end(JSON.stringify({
|
|
228
|
-
error: "Internal Server Error",
|
|
229
|
-
message: err.message
|
|
230
|
-
}));
|
|
252
|
+
if (aborted || resWrapper.finished) return;
|
|
253
|
+
if (hookIndex >= hooks.length) {
|
|
254
|
+
finishUpgrade();
|
|
255
|
+
return;
|
|
231
256
|
}
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
257
|
+
const HookClass = hooks[hookIndex++];
|
|
258
|
+
const hookInstance = typeof HookClass === "function" ? new HookClass() : HookClass;
|
|
259
|
+
let doneCalled = false;
|
|
260
|
+
const done = /* @__PURE__ */ __name((doneError) => {
|
|
261
|
+
if (doneCalled) return;
|
|
262
|
+
doneCalled = true;
|
|
263
|
+
runNextHook(doneError);
|
|
264
|
+
}, "done");
|
|
265
|
+
try {
|
|
266
|
+
hookInstance.handle(reqWrapper, resWrapper, done);
|
|
267
|
+
} catch (err) {
|
|
268
|
+
done(err);
|
|
269
|
+
}
|
|
270
|
+
}, "runNextHook");
|
|
271
|
+
runNextHook();
|
|
242
272
|
}, "upgrade"),
|
|
243
273
|
open: /* @__PURE__ */ __name((ws) => {
|
|
244
274
|
if (behaviors.open) {
|
package/express.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
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
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "owebjs",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.7-dev",
|
|
4
4
|
"description": "A flexible and modern web framework built on top of Fastify",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -22,8 +22,9 @@
|
|
|
22
22
|
"scripts": {
|
|
23
23
|
"start": "node .",
|
|
24
24
|
"build": "tsup",
|
|
25
|
-
"dev": "tsup && node .",
|
|
26
|
-
"test": "tsup &&
|
|
25
|
+
"dev": "tsup && node test/index.js",
|
|
26
|
+
"test": "tsup && vitest run --config test/vitest.config.mts",
|
|
27
|
+
"test:watch": "tsup && vitest --config test/vitest.config.mts",
|
|
27
28
|
"format": "prettier --write . --ignore-path .gitignore"
|
|
28
29
|
},
|
|
29
30
|
"homepage": "https://github.com/owebjs/oweb",
|
|
@@ -59,7 +60,8 @@
|
|
|
59
60
|
"prettier": "^3.0.3",
|
|
60
61
|
"tslib": "^2.6.2",
|
|
61
62
|
"tsup": "^8.5.0",
|
|
62
|
-
"typescript": "^5.2.2"
|
|
63
|
+
"typescript": "^5.2.2",
|
|
64
|
+
"vitest": "^3.2.4"
|
|
63
65
|
},
|
|
64
66
|
"type": "module",
|
|
65
67
|
"pnpm": {
|
package/purehttp.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
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
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
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
|
+
});
|