From 369b4a551ffed7f31d147c0c6246d3c8fa0c8e41 Mon Sep 17 00:00:00 2001 From: Alex Hultman Date: Fri, 5 Jun 2020 17:09:19 +0200 Subject: [PATCH] Add UpgradeAsync example, update examples --- examples/Backpressure.js | 4 +-- examples/Broadcast.js | 2 +- examples/PubSub.js | 12 +++---- examples/Upgrade.js | 10 ++++-- examples/UpgradeAsync.js | 76 ++++++++++++++++++++++++++++++++++++++++ examples/WebSockets.js | 2 +- 6 files changed, 93 insertions(+), 13 deletions(-) create mode 100644 examples/UpgradeAsync.js diff --git a/examples/Backpressure.js b/examples/Backpressure.js index 4f148ac..d3fad10 100644 --- a/examples/Backpressure.js +++ b/examples/Backpressure.js @@ -35,8 +35,8 @@ const app = uWS./*SSL*/App({ /* We need a slightly higher timeout for this crazy example */ idleTimeout: 60, /* Handlers */ - open: (ws, req) => { - console.log('A WebSocket connected via URL: ' + req.getUrl() + '! Pushing data now!'); + open: (ws) => { + console.log('A WebSocket connected!'); /* We begin our example by sending until we have backpressure */ while (ws.getBufferedAmount() < backpressure) { ws.send("This is a message, let's call it " + messageNumber); diff --git a/examples/Broadcast.js b/examples/Broadcast.js index 88e7fed..3e1a090 100644 --- a/examples/Broadcast.js +++ b/examples/Broadcast.js @@ -14,7 +14,7 @@ const app = uWS./*SSL*/App({ idleTimeout: 10, /* Handlers */ - open: (ws, req) => { + open: (ws) => { /* Let this client listen to topic "broadcast" */ ws.subscribe('broadcast'); }, diff --git a/examples/PubSub.js b/examples/PubSub.js index e3b7683..625333e 100644 --- a/examples/PubSub.js +++ b/examples/PubSub.js @@ -9,18 +9,16 @@ const app = uWS./*SSL*/App({ passphrase: '1234' }).ws('/*', { /* Options */ - compression: 0, + compression: uWS.SHARED_COMPRESSOR, maxPayloadLength: 16 * 1024 * 1024, idleTimeout: 10, - // would be nice to have maxBackpressure to automatically close slow receivers + maxBackpressure: 1024, - /* Setting 1: merge messages in one, or keep them as separate WebSocket frames - mergePublishedMessages */ - /* Setting 2: compression on/off - cannot have dedicated compressor for pubsub yet */ - /* Setting 3: maxBackpressure - when we want to automatically terminate a slow receiver */ - /* Setting 4: send to all including us, or not? That's not a setting really just use ws.publish or global uWS.publish */ + /* Todo, Setting 1: merge messages in one, or keep them as separate WebSocket frames - mergePublishedMessages */ + /* Todo, Setting 4: send to all including us, or not? That's not a setting really just use ws.publish or global uWS.publish */ /* Handlers */ - open: (ws, req) => { + open: (ws) => { /* Let this client listen to all sensor topics */ ws.subscribe('home/sensors/#'); }, diff --git a/examples/Upgrade.js b/examples/Upgrade.js index a66b148..1d6b1d8 100644 --- a/examples/Upgrade.js +++ b/examples/Upgrade.js @@ -9,17 +9,23 @@ const app = uWS./*SSL*/App({ passphrase: '1234' }).ws('/*', { /* Options */ - compression: 0, + compression: uWS.SHARED_COMPRESSOR, maxPayloadLength: 16 * 1024 * 1024, idleTimeout: 10, /* Handlers */ upgrade: (res, req, context) => { console.log('An Http connection wants to become WebSocket, URL: ' + req.getUrl() + '!'); - res.upgrade({url: req.getUrl()}, req.getHeader('sec-websocket-key'), + /* This immediately calls open handler, you must not use res after this call */ + res.upgrade({ + url: req.getUrl() + }, + /* Spell these correctly */ + req.getHeader('sec-websocket-key'), req.getHeader('sec-websocket-protocol'), req.getHeader('sec-websocket-extensions'), context); + }, open: (ws) => { console.log('A WebSocket connected with URL: ' + ws.url); diff --git a/examples/UpgradeAsync.js b/examples/UpgradeAsync.js new file mode 100644 index 0000000..58faee2 --- /dev/null +++ b/examples/UpgradeAsync.js @@ -0,0 +1,76 @@ +/* A quite detailed WebSockets upgrade example "async" */ + +const uWS = require('../dist/uws.js'); +const port = 9001; + +const app = uWS./*SSL*/App({ + key_file_name: 'misc/key.pem', + cert_file_name: 'misc/cert.pem', + passphrase: '1234' +}).ws('/*', { + /* Options */ + compression: uWS.SHARED_COMPRESSOR, + maxPayloadLength: 16 * 1024 * 1024, + idleTimeout: 10, + /* Handlers */ + upgrade: (res, req, context) => { + console.log('An Http connection wants to become WebSocket, URL: ' + req.getUrl() + '!'); + + /* Keep track of abortions */ + const upgradeAborted = {aborted: false}; + + /* You MUST copy data out of req here, as req is only valid within this immediate callback */ + const url = req.getUrl(); + const secWebSocketKey = req.getHeader('sec-websocket-key'); + const secWebSocketProtocol = req.getHeader('sec-websocket-protocol'); + const secWebSocketExtensions = req.getHeader('sec-websocket-extensions'); + + /* Simulate doing "async" work before upgrading */ + setTimeout(() => { + console.log("We are now done with our async task, let's upgrade the WebSocket!"); + + if (upgradeAborted.aborted) { + console.log("Ouch! Client disconnected before we could upgrade it!"); + /* You must not upgrade now */ + return; + } + + /* This immediately calls open handler, you must not use res after this call */ + res.upgrade({ + url: url + }, + /* Use our copies here */ + secWebSocketKey, + secWebSocketProtocol, + secWebSocketExtensions, + context); + }, 1000); + + /* You MUST register an abort handler to know if the upgrade was aborted by peer */ + res.onAborted(() => { + /* We can simply signal that we were aborted */ + upgradeAborted.aborted = true; + }); + }, + open: (ws) => { + console.log('A WebSocket connected with URL: ' + ws.url); + }, + message: (ws, message, isBinary) => { + /* Ok is false if backpressure was built up, wait for drain */ + let ok = ws.send(message, isBinary); + }, + drain: (ws) => { + console.log('WebSocket backpressure: ' + ws.getBufferedAmount()); + }, + close: (ws, code, message) => { + console.log('WebSocket closed'); + } +}).any('/*', (res, req) => { + res.end('Nothing to see here!'); +}).listen(port, (token) => { + if (token) { + console.log('Listening to port ' + port); + } else { + console.log('Failed to listen to port ' + port); + } +}); diff --git a/examples/WebSockets.js b/examples/WebSockets.js index c5bf0de..a8983a4 100644 --- a/examples/WebSockets.js +++ b/examples/WebSockets.js @@ -9,7 +9,7 @@ const app = uWS./*SSL*/App({ passphrase: '1234' }).ws('/*', { /* Options */ - compression: 0, + compression: uWS.SHARED_COMPRESSOR, maxPayloadLength: 16 * 1024 * 1024, idleTimeout: 10, /* Handlers */