Solo Solo - 22 days ago 5
Node.js Question

Passing extra arguments to callback function

websocketServer.on('connection', function(socket, req) {
socket.on('message', onMessage);

sub.subscribe('chat'); // sub: Redis subscription connection
sub.on('message', onSubMessage);
});

function onMessage(message) {
pub.publish('chat', message); // pub: Redis publishing connection
}

function onSubMessage(channel, message) {
// how to access 'socket' from here?
if (channel === 'chat') socket.send(message);
}


I'm trying to get away with as few state & bindings as possible, to make WS server efficient & to have the ability to just add more machines if I need to scale - state would only make this harder. Im still not understanding everything about Node memory management & garbage collection.

What would be the recommended solution in this case? Move
onSubMessage
into
connection
callback to access
socket
? But function would be then initialized on every connection?

What other choices do I have?




Little background about this:



The user opens a WebSocket connection with the server. If the user sends a message, it gets sent to Redis channel (might also know it as Pub/Sub topic) which broadcasts it to every subscribed client (
onSubMessage
). Redis Pub/Sub acts as a centralized broadcaster: I don't have to worry about different servers or state, Redis sends a message to everybody who is interested. Carefree scaling.

Answer Source

You can use bind() to pre-define an extra argument to the callback function:

...
sub.on('message', onSubMessage.bind(sub, socket));
...

function onSubMessage(socket, channel, message) {
  if (channel === 'chat') socket.send(message);
}

This does create a new function instance for every new connection, so there is probably not a real upside to using a wrapping function in terms of memory usage.