uwebsockets 1.0.0

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.
Files changed (98) hide show
  1. package/.gitattributes +3 -0
  2. package/.github/workflows/c-cpp.yml +92 -0
  3. package/.gitmodules +3 -0
  4. package/Makefile +11 -0
  5. package/README.md +58 -0
  6. package/build.c +185 -0
  7. package/docs/Makefile +2 -0
  8. package/docs/generated/.nojekyll +1 -0
  9. package/docs/generated/assets/highlight.css +22 -0
  10. package/docs/generated/assets/main.js +4 -0
  11. package/docs/generated/assets/search.js +1 -0
  12. package/docs/generated/assets/style.css +1280 -0
  13. package/docs/generated/enums/ListenOptions.html +70 -0
  14. package/docs/generated/functions/App.html +94 -0
  15. package/docs/generated/functions/SSLApp.html +93 -0
  16. package/docs/generated/functions/getParts.html +95 -0
  17. package/docs/generated/functions/us_listen_socket_close.html +93 -0
  18. package/docs/generated/functions/us_socket_local_port.html +93 -0
  19. package/docs/generated/index.html +131 -0
  20. package/docs/generated/interfaces/AppOptions.html +115 -0
  21. package/docs/generated/interfaces/HttpRequest.html +204 -0
  22. package/docs/generated/interfaces/HttpResponse.html +400 -0
  23. package/docs/generated/interfaces/MultipartField.html +88 -0
  24. package/docs/generated/interfaces/TemplatedApp.html +595 -0
  25. package/docs/generated/interfaces/WebSocket.html +303 -0
  26. package/docs/generated/interfaces/WebSocketBehavior.html +331 -0
  27. package/docs/generated/interfaces/us_listen_socket.html +89 -0
  28. package/docs/generated/interfaces/us_socket.html +89 -0
  29. package/docs/generated/interfaces/us_socket_context_t.html +89 -0
  30. package/docs/generated/types/CompressOptions.html +84 -0
  31. package/docs/generated/types/RecognizedString.html +89 -0
  32. package/docs/generated/variables/DEDICATED_COMPRESSOR_128KB.html +84 -0
  33. package/docs/generated/variables/DEDICATED_COMPRESSOR_16KB.html +84 -0
  34. package/docs/generated/variables/DEDICATED_COMPRESSOR_256KB.html +84 -0
  35. package/docs/generated/variables/DEDICATED_COMPRESSOR_32KB.html +84 -0
  36. package/docs/generated/variables/DEDICATED_COMPRESSOR_3KB.html +84 -0
  37. package/docs/generated/variables/DEDICATED_COMPRESSOR_4KB.html +84 -0
  38. package/docs/generated/variables/DEDICATED_COMPRESSOR_64KB.html +84 -0
  39. package/docs/generated/variables/DEDICATED_COMPRESSOR_8KB.html +84 -0
  40. package/docs/generated/variables/DEDICATED_DECOMPRESSOR.html +84 -0
  41. package/docs/generated/variables/DEDICATED_DECOMPRESSOR_16KB.html +84 -0
  42. package/docs/generated/variables/DEDICATED_DECOMPRESSOR_1KB.html +84 -0
  43. package/docs/generated/variables/DEDICATED_DECOMPRESSOR_2KB.html +84 -0
  44. package/docs/generated/variables/DEDICATED_DECOMPRESSOR_32KB.html +84 -0
  45. package/docs/generated/variables/DEDICATED_DECOMPRESSOR_4KB.html +84 -0
  46. package/docs/generated/variables/DEDICATED_DECOMPRESSOR_512B.html +84 -0
  47. package/docs/generated/variables/DEDICATED_DECOMPRESSOR_8KB.html +84 -0
  48. package/docs/generated/variables/DISABLED.html +84 -0
  49. package/docs/generated/variables/SHARED_COMPRESSOR.html +84 -0
  50. package/docs/generated/variables/SHARED_DECOMPRESSOR.html +84 -0
  51. package/docs/index.d.ts +395 -0
  52. package/docs/report.pdf +0 -0
  53. package/docs/tsconfig.json +11 -0
  54. package/examples/AsyncFunction.js +43 -0
  55. package/examples/AutomaticPortSelection.js +20 -0
  56. package/examples/Backpressure.js +75 -0
  57. package/examples/Broadcast.js +39 -0
  58. package/examples/GracefulShutdown.js +39 -0
  59. package/examples/H3lloWorld.js +23 -0
  60. package/examples/Headers.js +31 -0
  61. package/examples/HelloWorld.js +18 -0
  62. package/examples/JsonPost.js +72 -0
  63. package/examples/ProxyProtocol.js +25 -0
  64. package/examples/PubSub.js +57 -0
  65. package/examples/RateLimit.js +69 -0
  66. package/examples/Router.js +30 -0
  67. package/examples/ServerName.js +34 -0
  68. package/examples/ServerSentEvents.js +48 -0
  69. package/examples/SlowReceiver.js +53 -0
  70. package/examples/Upgrade.js +51 -0
  71. package/examples/UpgradeAsync.js +80 -0
  72. package/examples/Upload.js +36 -0
  73. package/examples/VideoStreamer.js +115 -0
  74. package/examples/VideoStreamerSync.js +42 -0
  75. package/examples/WebSockets.js +37 -0
  76. package/examples/WorkerThreads.js +33 -0
  77. package/misc/Manycast latency comparison [lower is better].png +0 -0
  78. package/misc/addon.pro +24 -0
  79. package/misc/cert.pem +21 -0
  80. package/misc/chart.png +0 -0
  81. package/misc/features_strip.png +0 -0
  82. package/misc/host.pro +31 -0
  83. package/misc/key.pem +28 -0
  84. package/misc/logo.svg +1 -0
  85. package/misc/streaming.png +0 -0
  86. package/package.json +41 -0
  87. package/src/AppWrapper.h +734 -0
  88. package/src/HttpRequestWrapper.h +196 -0
  89. package/src/HttpResponseWrapper.h +463 -0
  90. package/src/Utilities.h +172 -0
  91. package/src/WebSocketWrapper.h +348 -0
  92. package/src/addon.cpp +437 -0
  93. package/src/host.cpp +115 -0
  94. package/src/uws.js +24 -0
  95. package/tests/Autobahn.js +102 -0
  96. package/tests/Hammer.js +203 -0
  97. package/tests/Makefile +2 -0
  98. package/tests/fuzzingclient.json +28 -0
@@ -0,0 +1,31 @@
1
+ /* Example of looping over all headers (not recommended as production solution,
2
+ * do NOT use this to "solve" your problems with headers, use ONLY for debugging) */
3
+
4
+ const uWS = require('../dist/uws.js');
5
+ const port = 9001;
6
+
7
+ const app = uWS./*SSL*/App({
8
+ key_file_name: 'misc/key.pem',
9
+ cert_file_name: 'misc/cert.pem',
10
+ passphrase: '1234'
11
+ }).get('/*', (res, req) => {
12
+
13
+ res.write('<h2>Hello, your headers are:</h2><ul>');
14
+
15
+ req.forEach((k, v) => {
16
+ res.write('<li>');
17
+ res.write(k);
18
+ res.write(' = ');
19
+ res.write(v);
20
+ res.write('</li>');
21
+ });
22
+
23
+ res.end('</ul>');
24
+
25
+ }).listen(port, (token) => {
26
+ if (token) {
27
+ console.log('Listening to port ' + port);
28
+ } else {
29
+ console.log('Failed to listen to port ' + port);
30
+ }
31
+ });
@@ -0,0 +1,18 @@
1
+ /* Minimal SSL/non-SSL example */
2
+
3
+ const uWS = require('../dist/uws.js');
4
+ const port = 9001;
5
+
6
+ const app = uWS./*SSL*/App({
7
+ key_file_name: 'misc/key.pem',
8
+ cert_file_name: 'misc/cert.pem',
9
+ passphrase: '1234'
10
+ }).get('/*', (res, req) => {
11
+ res.end('Hello World!');
12
+ }).listen(port, (token) => {
13
+ if (token) {
14
+ console.log('Listening to port ' + port);
15
+ } else {
16
+ console.log('Failed to listen to port ' + port);
17
+ }
18
+ });
@@ -0,0 +1,72 @@
1
+ /* Simple example of getting JSON from a POST */
2
+
3
+ const uWS = require('../dist/uws.js');
4
+ const port = 9001;
5
+
6
+ const app = uWS./*SSL*/App({
7
+ key_file_name: 'misc/key.pem',
8
+ cert_file_name: 'misc/cert.pem',
9
+ passphrase: '1234'
10
+ }).post('/*', (res, req) => {
11
+
12
+ /* Note that you cannot read from req after returning from here */
13
+ let url = req.getUrl();
14
+
15
+ /* Read the body until done or error */
16
+ readJson(res, (obj) => {
17
+ console.log('Posted to ' + url + ': ');
18
+ console.log(obj);
19
+
20
+ res.end('Thanks for this json!');
21
+ }, () => {
22
+ /* Request was prematurely aborted or invalid or missing, stop reading */
23
+ console.log('Invalid JSON or no data at all!');
24
+ });
25
+
26
+ }).listen(port, (token) => {
27
+ if (token) {
28
+ console.log('Listening to port ' + port);
29
+ } else {
30
+ console.log('Failed to listen to port ' + port);
31
+ }
32
+ });
33
+
34
+ /* Helper function for reading a posted JSON body */
35
+ function readJson(res, cb, err) {
36
+ let buffer;
37
+ /* Register data cb */
38
+ res.onData((ab, isLast) => {
39
+ let chunk = Buffer.from(ab);
40
+ if (isLast) {
41
+ let json;
42
+ if (buffer) {
43
+ try {
44
+ json = JSON.parse(Buffer.concat([buffer, chunk]));
45
+ } catch (e) {
46
+ /* res.close calls onAborted */
47
+ res.close();
48
+ return;
49
+ }
50
+ cb(json);
51
+ } else {
52
+ try {
53
+ json = JSON.parse(chunk);
54
+ } catch (e) {
55
+ /* res.close calls onAborted */
56
+ res.close();
57
+ return;
58
+ }
59
+ cb(json);
60
+ }
61
+ } else {
62
+ if (buffer) {
63
+ buffer = Buffer.concat([buffer, chunk]);
64
+ } else {
65
+ buffer = Buffer.concat([chunk]);
66
+ }
67
+ }
68
+ });
69
+
70
+ /* Register error cb */
71
+ res.onAborted(err);
72
+ }
@@ -0,0 +1,25 @@
1
+ /* Minimal SSL/non-SSL example using PROXY Protocol v2 */
2
+
3
+ const uWS = require('../dist/uws.js');
4
+ const port = 3000;
5
+
6
+ const app = uWS./*SSL*/App({
7
+ key_file_name: 'misc/key.pem',
8
+ cert_file_name: 'misc/cert.pem',
9
+ passphrase: '1234'
10
+ }).get('/*', (res, req) => {
11
+ /* Respond with their addresses */
12
+ res.cork(() => {
13
+ res.write('<html><h1>');
14
+ res.write('Your proxied IP is: ' + Buffer.from(res.getProxiedRemoteAddressAsText()).toString());
15
+ res.write('</h1><h1>');
16
+ res.write('Your IP as seen by the origin server is: ' + Buffer.from(res.getRemoteAddressAsText()).toString());
17
+ res.end('</h1></html>');
18
+ });
19
+ }).listen(port, (listenSocket) => {
20
+ if (listenSocket) {
21
+ console.log('Listening to port ' + port);
22
+ } else {
23
+ console.log('Failed to listen to port ' + port);
24
+ }
25
+ });
@@ -0,0 +1,57 @@
1
+ /* Simple pub/sub example (WIP) */
2
+
3
+ const uWS = require('../dist/uws.js');
4
+ const port = 9001;
5
+
6
+ const app = uWS./*SSL*/App({
7
+ key_file_name: 'misc/key.pem',
8
+ cert_file_name: 'misc/cert.pem',
9
+ passphrase: '1234'
10
+ }).ws('/*', {
11
+ /* Options */
12
+ compression: uWS.SHARED_COMPRESSOR,
13
+ maxPayloadLength: 16 * 1024 * 1024,
14
+ idleTimeout: 10,
15
+ maxBackpressure: 1024,
16
+
17
+ /* Todo, Setting 1: merge messages in one, or keep them as separate WebSocket frames - mergePublishedMessages */
18
+ /* Todo, Setting 4: send to all including us, or not? That's not a setting really just use ws.publish or global uWS.publish */
19
+
20
+ /* Handlers */
21
+ open: (ws) => {
22
+ /* Let this client listen to all sensor topics */
23
+ ws.subscribe('home/sensors/#');
24
+ },
25
+ message: (ws, message, isBinary) => {
26
+ /* Parse this message according to some application
27
+ * protocol such as JSON [action, topic, message] */
28
+
29
+ /* Let's pretend this was a temperature message
30
+ * [pub, home/sensors/temperature, message] */
31
+ ws.publish('home/sensors/temperature', message);
32
+
33
+ /* Let's also pretend this was a light message
34
+ * [pub, home/sensors/light, message] */
35
+ ws.publish('home/sensors/light', message);
36
+
37
+ /* If you have good imagination you can also
38
+ * pretend some message was a subscription
39
+ * like so: [sub, /home/sensors/humidity].
40
+ * I hope you get how any application protocol
41
+ * can be implemented with these helpers. */
42
+ },
43
+ drain: (ws) => {
44
+
45
+ },
46
+ close: (ws, code, message) => {
47
+ /* The library guarantees proper unsubscription at close */
48
+ }
49
+ }).any('/*', (res, req) => {
50
+ res.end('Nothing to see here!');
51
+ }).listen(port, (token) => {
52
+ if (token) {
53
+ console.log('Listening to port ' + port);
54
+ } else {
55
+ console.log('Failed to listen to port ' + port);
56
+ }
57
+ });
@@ -0,0 +1,69 @@
1
+ /* RateLimit example */
2
+
3
+ const uWS = require('../dist/uws.js');
4
+ const port = 9001;
5
+
6
+ const RateLimit = (limit, interval) => { let now = 0; const last = Symbol(), count = Symbol(); setInterval(() => ++now, interval); return ws => { if (ws[last] != now) { ws[last] = now; ws[count] = 1 } else { return ++ws[count] > limit } } }
7
+ const rateLimit = RateLimit(1, 10000) // limit is: 1 message per 10 seconds.
8
+ const rateLimit2 = RateLimit(10, 2000) // limit per interval (milliseconds)
9
+
10
+
11
+ const app = uWS./*SSL*/App({
12
+ key_file_name: 'misc/key.pem',
13
+ cert_file_name: 'misc/cert.pem',
14
+ passphrase: '1234'
15
+ }).ws('/*', {
16
+ /* Options */
17
+ compression: uWS.SHARED_COMPRESSOR,
18
+ maxPayloadLength: 16 * 1024 * 1024,
19
+ idleTimeout: 10,
20
+ /* Handlers */
21
+ open: (ws) => {
22
+ console.log('A WebSocket connected!');
23
+ },
24
+ message: async (ws, message, isBinary) => {
25
+
26
+ // rateLimit(ws) returns true if over limit
27
+ if (rateLimit(ws)) {
28
+ /*
29
+ Do as you wish, personally, I prefer to inform the client, do Log,
30
+ and close the connection if over limit happened.
31
+ or you can just ignore its message and just return.
32
+ */
33
+ const dataToSendToClient = {
34
+ action: 'info',
35
+ data: {
36
+ message: {
37
+ english: 'over limit! please slow down.',
38
+ farsi: 'یواش‌تر'
39
+ }
40
+ }
41
+ }
42
+ await ws.send(JSON.stringify(dataToSendToClient));
43
+ console.warn('rate limit hit!');
44
+ return ws.end();
45
+ }
46
+
47
+ //or maybe different type of message or /endpoint needs different limit
48
+ if (ws.type2 && rateLimit2(ws)) {
49
+ console.warn('type2 is over limit');
50
+ return ws.end();
51
+ }
52
+
53
+ // rest of message code goes here ...
54
+ },
55
+ drain: (ws) => {
56
+ console.log('WebSocket backpressure: ' + ws.getBufferedAmount());
57
+ },
58
+ close: (ws, code, message) => {
59
+ console.log('WebSocket closed');
60
+ }
61
+ }).any('/*', (res, req) => {
62
+ res.end('Nothing to see here!');
63
+ }).listen(port, (token) => {
64
+ if (token) {
65
+ console.log('Listening to port ' + port);
66
+ } else {
67
+ console.log('Failed to listen to port ' + port);
68
+ }
69
+ });
@@ -0,0 +1,30 @@
1
+ /* Simple demonstration of some router features */
2
+
3
+ const uWS = require('../dist/uws.js');
4
+ const port = 9001;
5
+
6
+ const app = uWS./*SSL*/App({
7
+ key_file_name: 'misc/key.pem',
8
+ cert_file_name: 'misc/cert.pem',
9
+ passphrase: '1234'
10
+ }).any('/anything', (res, req) => {
11
+ res.end('Any route with method: ' + req.getMethod());
12
+ }).get('/user/agent', (res, req) => {
13
+ /* Read headers */
14
+ res.end('Your user agent is: ' + req.getHeader('user-agent') + ' thank you, come again!');
15
+ }).get('/static/yes', (res, req) => {
16
+ /* Static match */
17
+ res.end('This is very static');
18
+ }).get('/candy/:kind', (res, req) => {
19
+ /* Parameters */
20
+ res.end('So you want candy? Have some ' + req.getParameter(0) + '!');
21
+ }).get('/*', (res, req) => {
22
+ /* Wildcards - make sure to catch them last */
23
+ res.end('Nothing to see here!');
24
+ }).listen(port, (token) => {
25
+ if (token) {
26
+ console.log('Listening to port ' + port);
27
+ } else {
28
+ console.log('Failed to listen to port ' + port);
29
+ }
30
+ });
@@ -0,0 +1,34 @@
1
+ /* Minimal SSL example using ServerNameIndication */
2
+
3
+ const uWS = require('../dist/uws.js');
4
+ const port = 9001;
5
+
6
+ const app = uWS.SSLApp({
7
+ key_file_name: 'misc/key.pem',
8
+ cert_file_name: 'misc/cert.pem',
9
+ passphrase: '1234'
10
+ }).missingServerName((hostname) => {
11
+
12
+ /* Note: You don't have to use this callback but can pre-load
13
+ * relevant server names up front. This callback is not "async",
14
+ * you either add the server name HERE IMMEDIATELY, or the hangshake
15
+ * will continue with default certificate (which will most likely fail) */
16
+
17
+ console.log("Hello! We are missing server name <" + hostname + ">");
18
+
19
+ /* We simply assume it is localhost, so adding it here */
20
+ app.addServerName("localhost", {
21
+ key_file_name: 'misc/key.pem',
22
+ cert_file_name: 'misc/cert.pem',
23
+ passphrase: '1234'
24
+ });
25
+
26
+ }).get('/*', (res, req) => {
27
+ res.end('Hello World!');
28
+ }).listen(port, (token) => {
29
+ if (token) {
30
+ console.log('Listening to port ' + port);
31
+ } else {
32
+ console.log('Failed to listen to port ' + port);
33
+ }
34
+ });
@@ -0,0 +1,48 @@
1
+ /* Server-sent events (EventSource) example */
2
+ /* curl -n localhost:9001 # check events by using curl */
3
+
4
+ const uWS = require('../dist/uws.js');
5
+ const port = 9001;
6
+
7
+ const headers = [
8
+ ['Content-Type', 'text/event-stream'],
9
+ ['Connection', 'keep-alive'],
10
+ ['Cache-Control', 'no-cache']
11
+ ]
12
+
13
+ function sendHeaders(res) {
14
+ for (const [header, value] of headers) {
15
+ res.writeHeader(header, value)
16
+ }
17
+ }
18
+
19
+ function serializeData(data) {
20
+ return `data: ${JSON.stringify(data)}\n\n`
21
+ }
22
+
23
+ const app = uWS./*SSL*/App({
24
+ key_file_name: 'misc/key.pem',
25
+ cert_file_name: 'misc/cert.pem',
26
+ passphrase: '1234'
27
+ }).get('/*', (res) => {
28
+ const clientId = Date.now()
29
+ console.log(`Client with id: ${clientId} connected, starting streaming`)
30
+ sendHeaders(res);
31
+ res.writeStatus('200 OK')
32
+
33
+ let intervalRef = setInterval(() => {
34
+ res.write(serializeData({ message: 'Hello world!' }))
35
+ }, 1000)
36
+
37
+ res.onAborted(() => {
38
+ clearInterval(intervalRef)
39
+ intervalRef = undefined
40
+ console.log(`Client with id: ${clientId} disconnected`)
41
+ })
42
+ }).listen(port, (token) => {
43
+ if (token) {
44
+ console.log('Listening to port ' + port);
45
+ } else {
46
+ console.log('Failed to listen to port ' + port);
47
+ }
48
+ });
@@ -0,0 +1,53 @@
1
+
2
+
3
+ const uWS = require('uWebSockets.js');
4
+ const port = 9001;
5
+
6
+ const wsc = require('ws');
7
+
8
+ const app = uWS.App().ws('/*', {
9
+ /* Options */
10
+ maxPayloadLength: 16 * 1024 * 1024,
11
+ idleTimeout: 10,
12
+ maxBackpressure: 1024,
13
+ closeOnBackpressureLimit: true, /* Enable or disable as needed */
14
+
15
+ /* Handlers */
16
+ open: (ws) => {
17
+ console.log("Client connected");
18
+ ws.subscribe('clock_feed');
19
+
20
+ /* Disable closeOnBackpressureLimit and see this lie around 1024 */
21
+ ws.clock = setInterval(() => {
22
+ console.log("Connected socket has " + ws.getBufferedAmount() + " bytes buffered");
23
+ }, 1000);
24
+ },
25
+ close: (ws, code, message) => {
26
+ clearInterval(ws.clock);
27
+ console.log("Client disconnected: " + code + ", " + message);
28
+ /* The library guarantees proper unsubscription at close */
29
+ }
30
+ }).listen(port, (listenSocket) => {
31
+ if (listenSocket) {
32
+ console.log('Listening to port ' + port);
33
+ } else {
34
+ console.log('Failed to listen to port ' + port);
35
+ }
36
+ });
37
+
38
+ /* Publish the time as fast as possible in a loop */
39
+ function sendTime() {
40
+ app.publish("clock_feed", Date.now().toString());
41
+ setImmediate(sendTime);
42
+ }
43
+ sendTime();
44
+
45
+ /* Make a connection to the server */
46
+ const ws = new wsc.WebSocket('ws://localhost:9001');
47
+ ws.on('message', function message(data) {
48
+ console.log('received: %s', data);
49
+
50
+ /* If we pause receive, we will become slow receiver */
51
+ console.log("Will become slow receiver");
52
+ ws._socket.pause();
53
+ });
@@ -0,0 +1,51 @@
1
+ /* A quite detailed WebSockets example */
2
+
3
+ const uWS = require('../dist/uws.js');
4
+ const port = 9001;
5
+
6
+ const app = uWS./*SSL*/App({
7
+ key_file_name: 'misc/key.pem',
8
+ cert_file_name: 'misc/cert.pem',
9
+ passphrase: '1234'
10
+ }).ws('/*', {
11
+ /* Options */
12
+ compression: uWS.SHARED_COMPRESSOR,
13
+ maxPayloadLength: 16 * 1024 * 1024,
14
+ idleTimeout: 10,
15
+ /* Handlers */
16
+ upgrade: (res, req, context) => {
17
+ console.log('An Http connection wants to become WebSocket, URL: ' + req.getUrl() + '!');
18
+
19
+ /* This immediately calls open handler, you must not use res after this call */
20
+ res.upgrade({
21
+ myData: req.getUrl() /* First argument is UserData (see WebSocket.getUserData()) */
22
+ },
23
+ /* Spell these correctly */
24
+ req.getHeader('sec-websocket-key'),
25
+ req.getHeader('sec-websocket-protocol'),
26
+ req.getHeader('sec-websocket-extensions'),
27
+ context);
28
+
29
+ },
30
+ open: (ws) => {
31
+ console.log('A WebSocket connected with URL: ' + ws.myData);
32
+ },
33
+ message: (ws, message, isBinary) => {
34
+ /* Ok is false if backpressure was built up, wait for drain */
35
+ let ok = ws.send(message, isBinary);
36
+ },
37
+ drain: (ws) => {
38
+ console.log('WebSocket backpressure: ' + ws.getBufferedAmount());
39
+ },
40
+ close: (ws, code, message) => {
41
+ console.log('WebSocket closed');
42
+ }
43
+ }).any('/*', (res, req) => {
44
+ res.end('Nothing to see here!');
45
+ }).listen(port, (token) => {
46
+ if (token) {
47
+ console.log('Listening to port ' + port);
48
+ } else {
49
+ console.log('Failed to listen to port ' + port);
50
+ }
51
+ });
@@ -0,0 +1,80 @@
1
+ /* A quite detailed WebSockets upgrade example "async" */
2
+
3
+ const uWS = require('../dist/uws.js');
4
+ const port = 9001;
5
+
6
+ const app = uWS./*SSL*/App({
7
+ key_file_name: 'misc/key.pem',
8
+ cert_file_name: 'misc/cert.pem',
9
+ passphrase: '1234'
10
+ }).ws('/*', {
11
+ /* Options */
12
+ compression: uWS.SHARED_COMPRESSOR,
13
+ maxPayloadLength: 16 * 1024 * 1024,
14
+ idleTimeout: 10,
15
+ /* Handlers */
16
+ upgrade: (res, req, context) => {
17
+ console.log('An Http connection wants to become WebSocket, URL: ' + req.getUrl() + '!');
18
+
19
+ /* Keep track of abortions */
20
+ const upgradeAborted = {aborted: false};
21
+
22
+ /* You MUST copy data out of req here, as req is only valid within this immediate callback */
23
+ const url = req.getUrl();
24
+ const secWebSocketKey = req.getHeader('sec-websocket-key');
25
+ const secWebSocketProtocol = req.getHeader('sec-websocket-protocol');
26
+ const secWebSocketExtensions = req.getHeader('sec-websocket-extensions');
27
+
28
+ /* Simulate doing "async" work before upgrading */
29
+ setTimeout(() => {
30
+ console.log("We are now done with our async task, let's upgrade the WebSocket!");
31
+
32
+ if (upgradeAborted.aborted) {
33
+ console.log("Ouch! Client disconnected before we could upgrade it!");
34
+ /* You must not upgrade now */
35
+ return;
36
+ }
37
+
38
+ /* Cork any async response including upgrade */
39
+ res.cork(() => {
40
+ /* This immediately calls open handler, you must not use res after this call */
41
+ res.upgrade(
42
+ { url: url },
43
+ /* Use our copies here */
44
+ secWebSocketKey,
45
+ secWebSocketProtocol,
46
+ secWebSocketExtensions,
47
+ context
48
+ );
49
+ });
50
+
51
+ }, 1000);
52
+
53
+ /* You MUST register an abort handler to know if the upgrade was aborted by peer */
54
+ res.onAborted(() => {
55
+ /* We can simply signal that we were aborted */
56
+ upgradeAborted.aborted = true;
57
+ });
58
+ },
59
+ open: (ws) => {
60
+ console.log('A WebSocket connected with URL: ' + ws.url);
61
+ },
62
+ message: (ws, message, isBinary) => {
63
+ /* Ok is false if backpressure was built up, wait for drain */
64
+ let ok = ws.send(message, isBinary);
65
+ },
66
+ drain: (ws) => {
67
+ console.log('WebSocket backpressure: ' + ws.getBufferedAmount());
68
+ },
69
+ close: (ws, code, message) => {
70
+ console.log('WebSocket closed');
71
+ }
72
+ }).any('/*', (res, req) => {
73
+ res.end('Nothing to see here!');
74
+ }).listen(port, (token) => {
75
+ if (token) {
76
+ console.log('Listening to port ' + port);
77
+ } else {
78
+ console.log('Failed to listen to port ' + port);
79
+ }
80
+ });
@@ -0,0 +1,36 @@
1
+ /* Minimal POST example a SSL/non-SSL */
2
+ /* todo: proper throttling, better example */
3
+
4
+ /* a good example would be using the router to get
5
+ * a file name and stream that file to disk */
6
+
7
+ const uWS = require('../dist/uws.js');
8
+ const port = 9001;
9
+
10
+ const app = uWS./*SSL*/App({
11
+ key_file_name: 'misc/key.pem',
12
+ cert_file_name: 'misc/cert.pem',
13
+ passphrase: '1234'
14
+ }).post('/*', (res, req) => {
15
+ console.log('Posted to ' + req.getUrl());
16
+ res.onData((chunk, isLast) => {
17
+ /* Buffer this anywhere you want to */
18
+ console.log('Got chunk of data with length ' + chunk.byteLength + ', isLast: ' + isLast);
19
+
20
+ /* We respond when we are done */
21
+ if (isLast) {
22
+ res.end('Thanks for the data!');
23
+ }
24
+ });
25
+
26
+ res.onAborted(() => {
27
+ /* Request was prematurely aborted, stop reading */
28
+ console.log('Eh, okay. Thanks for nothing!');
29
+ });
30
+ }).listen(port, (token) => {
31
+ if (token) {
32
+ console.log('Listening to port ' + port);
33
+ } else {
34
+ console.log('Failed to listen to port ' + port);
35
+ }
36
+ });