how to send a message to individual clients with socket.io with multiple server processes?

I'm about to begin with socket.io and this is more of a theoretical question, let's say that I want to send a message to a specific user with socket.io, normally I would have to store the socketid with the relevant userid and when sending, get the socketid and send to.

but what if I have mutliple server processes running ? I'll have to make sure the correct server that the client is actually connected to does the sending. is it possible ?

For multiple server instances, you need to have a caching service (memcache, redis) for authentication and a central message queue service (stormMQ, rabbitMQ, AQ, java-based mq) where all your node instances bind to. Thus, a Node instance binds to the message queue for each client / channel / whatever, and all the other bound Node instances receive the messages and forward them to the client.

The problem is typically about how to play with a WebSocket cluster:

  • Several front-end servers which will be in charge of handling bidirectional connections with each client. They form the WebSocket cluster.
  • Several back-end servers which will be in charge of handling the business logic of your application.

Each time the back-end wants to inform the client, it will send a request to the WebSocket cluster which has the responsibility to communicate with the client. A possible scenario:

  • Identify each WebSocket cluster's server with a unique id.
  • Identify each client with a unique id.
  • Each time a client will connect one of your WebSocket cluster's server, store its unique id along with the server's unique id in a a distributed key/value like database.
  • Thus you know which client is connected with which server.
  • The next time your back-end application wants to notify a client there are two possibilities:
    1. The pair (clientId, serverId) is not present in the database and you cannot inform the client.
    2. The pair (clientId, serverId) is present in the database, then you have to ask to the server identified by serverId to notify the client identified by clientId.

Notes:

  • Each WebSocket cluster's server can run a node.js instance supercharged with socket.io. It has to provide a route which will take the clientId as a parameter and will use socket.io to notify this client. Indeed, socket.io is aware of whcih client is using which socket on this server.
  • Every time your server will crash, you have to clean your database and remove all pairs which contain the server id.
  • Deploying a WebSocket cluster can be tedious, so you have commercial offers like Kaazing.
  • A good distributed key/value like database is Riak. It is better than Redis or Memcached for the above purpose because it can be easily distributed in a data-center and over several data-centers.