Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SocketIO scaling architecture and large rooms requirements

Tags:

We are using socketIO on a large chat application.

At some points we want to dispatch "presence" (user availability) to all other users.

io.in('room1').emit('availability:update', {userid='xxx', isAvailable: false});

room1 may contains a lot of users (500 max). We observe a significant raise in our NodeJS load when many availability updates are triggered.

The idea was to use something similar to redis store with Socket IO. Have web browser clients to connect to different NodeJS servers.

When we want to emit to a room we dispatch the "emit to room1" payload to all other NodeJS processes using Redis PubSub ZeroMQ or even RabbitMQ for persistence. Each process will itself call his own io.in('room1').emit to target his subset of connected users.

One of the concern with this setup is that the inter-process communication may become quite busy and I was wondering if it may become a problem in the future.

Here is the architecture I have in mind.

enter image description here

like image 975
coulix Avatar asked May 14 '14 12:05

coulix


People also ask

What is Socket.IO used for?

Socket.IO was created in 2010. It was developed to use open connections to facilitate realtime communication, still a relatively new phenomenon at the time. Socket.IO allows bi-directional communication between client and server.

What protocol does Socket.IO use?

Socket.IO primarily uses the WebSocket protocol with polling as a fallback option, while providing the same interface.

Is Socket.IO scalable?

Socket.IO servers can be replicated and scaled horizontally, to provide fault-tolerance (ie. if one server fails, your service would still work) and serve more users (ie. by adding more server capacity).

Is Socket.IO a TCP?

The Socket.IO library keeps an open TCP connection to the server, which may result in a high battery drain for your users.


2 Answers

Could you batch changes and only distribute them every 5 seconds or so? In other words, on each node server, simply take a 'snapshot' every X seconds of the current state of all users (e.g. 'connected', 'idle', etc.) and then send that to the other relevant servers in your cluster.

Each server then does the same, every 5 seconds or so it sends the same message - of only the changes in user state - as one batch object array to all connected clients.

Right now, I'm rather surprised you are attempting to send information about each user as a packet. Batching seems like it would solve your problem quite well, as it would also make better use of standard packet sizes that are normally transmitted via routers and switches.

like image 67
JoshuaJ Avatar answered Sep 25 '22 11:09

JoshuaJ


You are looking for this library: https://github.com/automattic/socket.io-redis

Which can be used with this emitter: https://github.com/Automattic/socket.io-emitter

like image 31
Mustafa Dokumacı Avatar answered Sep 25 '22 11:09

Mustafa Dokumacı