I am in the process of writing a back-end for a service such as Facebook Messenger or WhatsApp.
I started out following this splendid tutorial.
I do this with an API written in Python (Django).
Along side with this API, I have a Redis process and a node.js server running (localhost only). The node.js server uses the socket.io library for real-time communication through websockets
An HTTP-request containing a message can be sent from any client to the Django API, which in turn publishes the message to Redis on a certain channel.
The node.js server has subscribed to the Redis channel, and gets notified when such a message is published. Node keeps track of which sockets that are currently connected with an array of socket ids keyed with some user identifier.
I have a few questions about this:
1. Private messages
I would like to send a message targeted to a certain user. My initial approach is to have the HTTP-request (sent to Django) include which user that the message should reach. When this message reaches the node.js server (through redis), node can find that user in an array of clients. Django obviously(?) needs to know which socket.io socket belongs to which user. i.e. Django needs to know which user identifying key that node should use to grab the right socket.
Is this a good approach? Will the redis-server be a bottleneck since I only use one publishing channel? What happens if the target user of the message is offline when the source user sends the message? I would like to grab that event and send a push-notification.
This service wouldn't be any good if there was not functionality for starting and maintaining group conversations. From what I have read, I should create socket.io:s rooms for this. My question is then, how do i maintain the room between sessions? What if every user participating in a group conversation goes offline and are thereby removed from the node.js server:s array of clients. Can I somehow store rooms between sessions in the Django server?.
Any help and/or feedback/thoughts is greatly appreciated.
Node keeps track of which sockets that are currently connected with an array of socket ids keyed with some user identifier.
You pretty much said it there. Django does not need to know the socket id of the target user, but node.js does. If you want to send a message to user 3 you would sent to message + target user (or any other meta data you want) to redis. Node.js will look up the user by reading the element with the id 3 from the socket array and send the message to this connection. If there is no element with id = 3, the user is offline and you can send your push notification. Eather in node.js or by notifying the django server.
Since you want your rooms to be persistant you should store them in some kind of database like mysql or mongodb. The node.js server would create all the rooms and if a user connects you can look up in which rooms they participated using their user id. If they join a new room you have to update the database. If a new room is created, node.js needs to create the socket.io room and the database needs to be updated as well.