Handling multiple clients for Chat and Notification using Socket.io, RabbitMQ and Nodejs

Viewed 397

I am building a social media application which will have lots of people around who will use it. The application will have a chat feature with real-time notification feature also. The process I followed to build chat application are as follows:

Option 1: The same kind of application I have already built using socket.io and managed all the user's unique socket tokens in an array as the number of users was very low. Here, whenever the user exits from the socket I used to remove them from the array. While sending any chat messages or when any notification is fired I used to search the token of those receivers(users) from the array and emit it based on their respective socket token.

Option 2: Another application which I have built with a similar chat feature has been built using redis to store the token based on the user's id(key value pair). Here, the redis manages the user's tokens and the lists.

But now the current application will be having lots of users in the near future(maybe > 1M) . In that case I think the redis or any manually managed array will not be able to handle those users at a time. There is also a chance of message or notification loss which I already encountered using the above options. So, I came to the conclusion to use RabbitMQ to manage all this with socket.io.

My concern is what should be the process or best practice to do this. I got some solutions, among which I am confused which one to use or whether it is the correct way of implementation or not. Below are the list of processes I have in my mind:

  1. Create an API when the user sends a notification or chat message. If the receiver is connected to a real time server the socket.io will generate a unique token. If both the receiver and sender is online then the messages will be handled by socket.io. What if the message is not delivered? When should I save the message or notification in the database as there is no acknowledgement of it being received?

  2. 2nd thought is, suppose if the receiver is not online then a new queue(RabbitMQ) will be generated using its id and the message will be pushed into the queue. Now when that receiver(user) comes online it should look in the queue to get any message that is there for him or not, here the consumer will be required to grab the message and deliver it to the respective receiver. Here, do I need to save the socket.io token in redis? Should I use socket.io with RabbitMQ for real-time communication? This is the area where I am getting a bit confused. How to actually create it or manage it? Should I go with Firebase to handle all this?

  3. 3rd solution which I got in my mind is, first of all save the data in DB then look for the receiver whether he is online or not by searching the socket token stored in redis. If found then emit the message directly if not then create a new queue(auto generated RabbitMQ queue name) and save the info in redis. Now whenever the user comes online the consumer(separate process to consume or process task/messages) will first search if its value(unique queue name) with respective to its user-id is there in redis server or not. After that the consumer will look into the message queue based on the queue name found in the redis server and eventually notify the user.

When should I save the message in database? Should I save the message in DB then use Socket.io to notify or emit the payload? Should I create separate queue for each user in RabbitMQ if the receiver is offline? How to notify the user when it again gets online about the unread message using RabbitMQ?

Am I on the right path or it's entirely the wrong process. Please suggest your valuable feedback with solutions.

0 Answers
Related