Case Study: Web Sockets - deanrad/rx-helper GitHub Wiki
Web Sockets
Web Sockets are longer lived then a single request, so it's important that each client has its own handler, and that the handler is unsubscribed when that client disconnects. To do this with Rx-Helper will require:
- Naming each handler uniquely
- Storing a reference to the handler's subscription
We detect a client connection, and see its unique id like this:
io.on("connection", client => {
console.log(`Got a client connection: ${client.id}`)
// set up this client to get notifications via client.emit
})
Now we set up that client with a unique handler. For an example from the Hotel California repo:
io.on("connection", client => {
console.log(`Got a client connection: ${client.id}`)
const sub = agent.on("setOccupancy",
({ event }) => {
client.emit(event.type, event.payload);
},
{ name: `client-${client.id}` }
);
client.on("disconnect", () => {
sub.unsubscribe();
console.log("Client disconnected");
});
})
This code makes use of the fact that each call to agent.on()
returns a Subscription object, which can be used to shutdown the resources used by that WebSocket client calling unusbscribe()
on it. Internally, Rx-Helper maintains a list of helpers, keyed by their names, and we make sure that we utilize the WebSocket client id
which will be string like NLL16xXMBocMLF3mAAAB
, so that this subscription will.
Handlers in Rx-Helper are fault-isolated, meaning that if the client.emit
code fails for one client, that will not prevent other clients from recieving their notifications. Errors will, however cause that client to not be subscribed anymore. See the test suite for the specific errors and consequences. Understand that safely handling errors in a message-passing environment involves defining objects that represent errors, and catching exceptions, to harvest their causes into error objects when appropriate.