Introduction
Real-time chat is virtually any online communication that provides a real-time or live transmission of text messages from sender to receiver. A variety of software programs are available to enable real-time chat between individuals using Internet services. Chat messages are often brief so as to let other participants respond swiftly, thereby creating a feeling much like a spoken conversation. This mode of communication differentiates real-time chats from other forms of text-based online communications, including emails and Internet forums. Real-time chat uses Web-based apps, which permit communication that is usually addressed directly but is anonymous among users in a multi-user environment.
WebSockets are a great fit for applications like chats or simple games. Chat sessions are usually long-lived, with the client receiving messages from other participants over a long period of time. Chat sessions are also bidirectional – clients want to send chat messages, and see chat messages from others. Unlike regular HTTP requests, WebSocket connections can be kept open for a long time and have an easy interface for exchanging data between the client and server in the form of frames. WebSockets are also a widely supported technology. All modern browsers can work with WebSockets out of the box, and frameworks to work with WebSockets exist in many programming languages and on many platforms.
Prerequisite
Before we move on to implementation there are basic terms and technologies we need to be familiar with.
Kafka:
In order to handle large number of connections, we will be needing multiple instances of a server, thus there will be a need for a medium for server to server communication. In a very fast, reliable, persisted, fault-tolerance and zero downtime manner, Kafka offers a Pub-sub and queue-based messaging system. The producers send the message to a topic and the consumer can select any one of the message systems according to their wish.
Redis:
For keeping account of online users and managing messages between multiple servers we would be needing a fast and reliable database system. Redis delivers sub-millisecond response times, enabling millions of requests per second for real-time applications in industries like gaming, ad-tech, financial services, healthcare, and IoT. Today, Redis is one of the most popular open source engines today, named the "Most Loved" database by Stack Overflow for five consecutive years. Because of its fast performance, Redis is a popular choice for caching, session management, gaming, leaderboards, real-time analytics, geospatial, ride-hailing, chat/messaging, media streaming, and pub/sub apps.
Building a Chatting Application
Now, Since we have gotten familiar with the technologies we will be using, below is the design diagram for our application:

For our application, we will build a messaging server in Golang
Docker-compose setup
Below is the docker-compose file we will be using to set up our services:
In the above docker-compose.yml
file images used:
- For Redis:
bitnami/redis:latest
- For Kafka:
confluentinc/cp-kafka:latest
Now that we have set up out docker-compose file we need to establish our services with our server using golang.
For this we would be using golang library:
- For Redis:
github.com/gomodule/redigo/redis
- For Kafka:
github.com/segmentio/kafka-go
- For Websockets:
github.com/gorilla/websocket
To create a server lets create a server object to access the services:
To initialize these services below is the InitService()
function:
Now that we have initialized our services, we need to create a structure to encode-decode messages. Below is the structure we will be using:
The user in the structure will have recipient user ID and Message we need to send.
Creating WebSocket Handler
Now, we can start creating our handler to receive and send messages.
Let's start with initialing a handshake using Upgrade()
method:
Once handshake is done we need to check for sender user ID from parameters and mark him online. To do that we will be using Redis and userCons map to store connection object and tag user online:
Once we mark user online we will be sending user un-recieved messages which he may got when he was offline. We are storing un-recieved messages into our Redis Database:
Now once user received his messages we can start with chatting session we will be using 2 go func()
for that one will receive messages from websocket and broadcast it into kafka
and the other will receive messages from Kafka and send it to recipient via websocket. In case the recipient is offline, the messages send by the user will be stored into redis.
Above code receives message from kafka
and checks if recipient is connected to the server. If there exist a connection, server sends the message to recipient via websocket.
Above code receives json encoded
messages from websocket and decode it into the structure. If the recipient is online, the server will broadcast the message into kafka so that the server instance to which recipient is connected will receive the message. In case recipient is offline, the messages will be stores in redis.
Once the connection is disconnected, we will remove the connection object from the map and mark user as offline in redis.
It is worth to note that in the above code there are 2 channels for redis one store the user un-recieved messages and other to store user online status.
The code demonstrates how a multi-instance server chatting service will work and how messages will manage such a complex system.
Below is the main()
func we used for the server:
We can test this server by sending websocket request via postman. Below is the output snippets of postman:


Conclusion
In this blog, we explored real-time chatting service, their system-design and how the messages are handled. Also we have implemented a multi-server instance chatting service which is managed by services like Redis and Kafka, due to which we are able to transmit messages reliably between users with very low latency.