diff --git a/examples/PubSub.js b/examples/PubSub.js new file mode 100644 index 0000000..097141e --- /dev/null +++ b/examples/PubSub.js @@ -0,0 +1,41 @@ +/* Simple pub/sub example (WIP) */ + +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: 0, + maxPayloadLength: 16 * 1024 * 1024, + idleTimeout: 10, + // would be nice to have maxBackpressure to automatically close slow receivers + /* Handlers */ + open: (ws, req) => { + /* Let all new sockets subscribe to chat topic */ + ws.subscribe('chat'); + }, + message: (ws, message, isBinary) => { + console.log('Got WebSocket message!'); + /* If we get a message from any socket, we publish it to the chat topic */ + ws.publish('chat', message); + }, + drain: (ws) => { + + }, + close: (ws, code, message) => { + // here we need to properly unsubscribe + // ws.unsubscribe('*'); + } +}).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/src/WebSocketWrapper.h b/src/WebSocketWrapper.h index 33569fc..3586552 100644 --- a/src/WebSocketWrapper.h +++ b/src/WebSocketWrapper.h @@ -21,6 +21,27 @@ struct WebSocketWrapper { args.Holder()->SetAlignedPointerInInternalField(0, nullptr); } + /* Takes string topic */ + template + static void uWS_WebSocket_subscribe(const FunctionCallbackInfo &args) { + auto *ws = getWebSocket(args); + if (ws) { + NativeString topic(isolate, args[0]); + ws->subscribe(topic.getString()); + } + } + + /* Takes string topic, message */ + template + static void uWS_WebSocket_publish(const FunctionCallbackInfo &args) { + auto *ws = getWebSocket(args); + if (ws) { + NativeString topic(isolate, args[0]); + NativeString message(isolate, args[1]); + ws->publish(topic.getString(), message.getString()); + } + } + /* 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 */ @@ -95,6 +116,8 @@ struct WebSocketWrapper { wsTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "end"), FunctionTemplate::New(isolate, uWS_WebSocket_end)); wsTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "close"), FunctionTemplate::New(isolate, uWS_WebSocket_close)); wsTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "getBufferedAmount"), FunctionTemplate::New(isolate, uWS_WebSocket_getBufferedAmount)); + wsTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "subscribe"), FunctionTemplate::New(isolate, uWS_WebSocket_subscribe)); + wsTemplateLocal->PrototypeTemplate()->Set(String::NewFromUtf8(isolate, "publish"), FunctionTemplate::New(isolate, uWS_WebSocket_publish)); /* Create the template */ Local wsObjectLocal = wsTemplateLocal->GetFunction()->NewInstance(isolate->GetCurrentContext()).ToLocalChecked();