1
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.

2
  • How about wrapping the event: sub.on('message', function (channel, message) { onSubMessage(channel, message, socket); });? Commented Sep 26, 2017 at 10:53
  • @Phylogenesis That was my first instinct too but then I found this. Commented Sep 26, 2017 at 10:56

1 Answer 1

2

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.

Sign up to request clarification or add additional context in comments.

4 Comments

I guess I have to test it with high traffic because I have no idea what it exactly does & how it affects memory. Im trying to get around this problem or at least perform better.
@Solo there isn't going to be a better solution, though. You need to get socket into your handler, which means either binding, wrapping or moving the entire handler inside the connection handler.
Thanks, I have to accept the reality then. Some better than others?
@Solo you'd have to test, I wouldn't know which one would perform better.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.