I am currently working on a side project so I can learn new technologies and understand how the components fit together. For this project, I decided that I wanted to work on Chat Applications in the context of Distributed System and trying to replicate as much as possible to real live systems (i.e. Whatsapp, FB Messenger, Signal, etc). Below, I have added three different diagrams.
For this project, I have decided that I wanted to mimic the following communication features:
- One to One
- Chatrooms (many to many)
In the following diagram, User_1 wants to send a message to User_2 using a single node instance:
- Both User_1 and User_2 establish a WS connection to the Chat Service
- Both User_1 and User_2 sockets are added to a map of Users or to a map of Channels
- User_1 sends message to User_2.
- User_1 message is first stored in the Datastore and only then the message is broadcasted to User_2.
In the following diagram, User_1 wants to send a message to User_2 when two nodes (both publishers and consumers, both subscribed to the /messages/ topic) are present using a message queue:
- User_1 establishes a connection to ChatService_1 using WS.
- User_2 establishes a connection to ChatService_2 using WS.
- User_1 publishes a message to ChatService_1 that publishes it to the message broker which broadcasts the message to all the available consumers.
- User_2 receives the message from User_1 that is consumed by ChatService_2.
In the following diagram, User_1 wants to send a message to User_2 using the MQTT protocol (I understand that this might be similar to how FB implemented FB Messenger).
- User_1 requests the HTTP Service for the latest chat messages.
- User_1 publishes a message directly to the broker, the broker routes the message based on the userTopicID_2.
- User_2 receives the message from User_1 that was routed by the broker on userTopicID_2.
My limitations into understanding the flow and how things are glued together are the following:
In example 2:
- In this message flow, at what moment does a given message gets stored in the datastore? Is it possible for the message queue to store the message into the datastore?
- How does one keep track of each user sockets if the services are completely decoupled of each other? Would a KV store like REDIS be enough for this use case, while having a datastore for the chat messages instead?
In example 3:
- How does a MQTT client can authenticate with the MQTT broker? How can we confirm that User_1 is able to send messages to User_2?
- How can one implement some sort of indirection so the MQTT client (which is a mobile app) doesn't connect directly to the broker? Is it possible to use a LoadBalancer or another server in front of it?
- From a security perspective, would it be necessary for my MQTT client to authenticate with my broker?
Any suggestions or ideas would be very much appreciated!