diff --git a/src/WebSocketWrapper.h b/src/WebSocketWrapper.h index 2bcb49f..55d53f3 100644 --- a/src/WebSocketWrapper.h +++ b/src/WebSocketWrapper.h @@ -21,6 +21,19 @@ struct WebSocketWrapper { args.Holder()->SetAlignedPointerInInternalField(0, nullptr); } + /* It would make sense to call terminate "close" and call close "end" to line up with HTTP */ + /* That also makes sense seince close takes message and code -> you can end with a string message */ + + /* Takes nothing returns nothing */ + template + static void uWS_WebSocket_terminate(const FunctionCallbackInfo &args) { + auto *ws = getWebSocket(args); + if (ws) { + invalidateWsObject(args); + ws->terminate(); + } + } + /* Takes code, message, returns undefined */ template static void uWS_WebSocket_close(const FunctionCallbackInfo &args) { @@ -80,6 +93,7 @@ struct WebSocketWrapper { /* Register our functions */ wsTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "send"), FunctionTemplate::New(isolate, uWS_WebSocket_send)); wsTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "close"), FunctionTemplate::New(isolate, uWS_WebSocket_close)); + wsTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "terminate"), FunctionTemplate::New(isolate, uWS_WebSocket_terminate)); wsTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "getBufferedAmount"), FunctionTemplate::New(isolate, uWS_WebSocket_getBufferedAmount)); /* Create the template */ diff --git a/tests/Hammer.js b/tests/Hammer.js index 9ce031d..d91f56e 100644 --- a/tests/Hammer.js +++ b/tests/Hammer.js @@ -15,29 +15,41 @@ const port = 9001; let openedClientConnections = 0; let closedClientConnections = 0; +let listenSocket; + +const maxBackpressure = 50 * 1024 * 1024; +const maxPayloadSize = 5 * 1024 * 1024; +const largeBuffer = new ArrayBuffer(maxPayloadSize); + function printStatistics() { console.log('Opened clients ' + openedClientConnections); console.log('Closed clients ' + closedClientConnections + '\n'); } -let listenSocket; - /* 0 to 1-less than max */ function getRandomInt(max) { return Math.floor(Math.random() * Math.floor(max)); } +/* This gets called every time we either open a new connection, + * or it immediately land in websockets/ws error handler */ +function accountForConnection() { + /* Open more connections */ + if (++openedClientConnections < /*100*/ 1000) { + establishNewConnection(); + } else { + /* Stop listening */ + uWS.us_listen_socket_close(listenSocket); + } +} + function establishNewConnection() { const ws = new WebSocket('ws://localhost:' + port); ws.on('open', () => { - /* Open more connections */ - if (++openedClientConnections < 100) { - establishNewConnection(); - } else { - /* Stop listening */ - uWS.us_listen_socket_close(listenSocket); - } + /* Mark this socket as opened */ + ws._opened = true; + accountForConnection(); printStatistics(); performRandomClientAction(ws); @@ -48,21 +60,30 @@ function establishNewConnection() { performRandomClientAction(ws); }); + /* Close can be called more times than open, websockets/ws is really messy! */ ws.on('close', () => { + /* Check if this websocket really was opened first */ + if (!ws._opened) { + accountForConnection(); + } + closedClientConnections++; printStatistics(); + /* I guess there is no need for us to call anything + * here, websockets/ws will not send anything to us anyways */ //performRandomClientAction(ws); }); + + ws.on('error', () => { + /* We simply ignore errors. websockets/ws will call our close handler + * on errors, potentially before even calling the open handler */ + }); } -const maxBackpressure = 50 * 1024 * 1024; -const maxPayloadSize = 5 * 1024 * 1024; -const largeBuffer = new ArrayBuffer(maxPayloadSize); - /* Perform random websockets/ws action */ function performRandomClientAction(ws) { - /* 0, 1 but never 2 */ - let action = getRandomInt(2); + /* 0, 1, 2 but never 3 */ + let action = getRandomInt(3); /* Sending a message should have higher probability */ if (getRandomInt(100) < 80) { @@ -85,7 +106,6 @@ function performRandomClientAction(ws) { break; } case 2: { - /* This should correspond to hard us_socket_close */ ws.terminate(); break; } @@ -94,7 +114,8 @@ function performRandomClientAction(ws) { /* Perform random uWebSockets.js action */ function performRandomServerAction(ws, uniform) { - let action = getRandomInt(2); + /* 0, 1, 2 but never 3 */ + let action = getRandomInt(3); /* Sending a message should have higher probability, * except for when we are draining. */ @@ -104,7 +125,6 @@ function performRandomServerAction(ws, uniform) { } } - /* 0, 1 but never 2 */ switch (action) { case 0: { ws.close(); diff --git a/uWebSockets b/uWebSockets index 80322a5..ba10536 160000 --- a/uWebSockets +++ b/uWebSockets @@ -1 +1 @@ -Subproject commit 80322a5af73ed97b739315327e2cc5af65bc2f1e +Subproject commit ba10536f50bb5060cdaa0ce8725d506faa8ac1ce