hackerhasid hackerhasid - 1 month ago 10
Node.js Question

How does socket.io send messages across multiple servers?

The Socket.io API has the ability to send messages to all clients.

With one server and all sockets in memory, I understand how that server one can send a message to all its clients, that's pretty obvious. But what about with multiple servers using Redis to store the sockets?

If I have client a connected to server y and client b connected to server z (and a Redis box for the store) and I do

socket.broadcast.emit
on one server, the client on the other server will receive this message. How?

How do the clients that are actually connected to the other server get that message?


  • Is one server telling the other server to send a message to its connected client?

  • Is the server establishing its own connection to the client to send that message?


Answer

Socket.io uses MemoryStore by default, so all the connected clients will be stored in memory making it impossible (well, not quiet but more on that later) to send and receive events from clients connected to a different socket.io server.

One way to make all the socket.io servers receive all the events is that all servers use redis's pub-sub. So, instead using socket.emit one can publish to redis.

redis_client = require('redis').createClient();
redis_client.publish('channelName', data);

And all the socket servers subscribe to that channel through redis and upon receiving a message emit it to clients connected to them.

redis_sub = require('redis').createClient();
redis_sub.subscribe('channelName', 'moreChannels');

redis_sub.on("message", function (channel, message) {        
    socket.emit(channel, message);
});

Complicated Stuff !! But wait, turns out you dont actually need this sort of code to achieve the goal. Socket.io has RedisStore which essentially does what the code above is supposed to do in a nicer way so that you can write Socket.io code as you would write for a single server and will still get propagated over to other socket.io server through redis.

To summarise socket.io sends messages across multiple servers by using redis as the channel instead of memory.