It is a salable chat service based on socket.io and PUBSUB which provides horizontal sacling and save resources for chat service. There are three repositories related to this project.
chat server: https://github.com/kyopark2014/webchat-golang-chat
profile server: https://github.com/kyopark2014/webchat-golang-profile
web client: https://github.com/kyopark2014/webchat-js-webclient
The channel is reusuable between client and server. It is important to reduce the connection complexity of the server so that the number of capability to cover the number of user in a node.
The messages and notification are using a single queue so that the order of messsage and notification can be aligned easily. Also, it has a benefit to manage messages and notifications compared with other messagers which use diffenre queue for message and notification.
User profile can be share between members which can improve user experience.
The notifications of delivery and display are useful for convinient chat service. Think about the popular messenger, slack which is also using websocket(socket.io) but it doesn't provide deliver and notifcation functionalities.
The groupchat is based on PUBSUB which has a strength for groupchat. Also, the number of participants is not limited and can be easily scaled up.
Web browser has a benefit for availability since all computer has a browser which measn that users can easily message service.
There are two connection ways between client and server. Socket.io is used for chat session and REST API is used for call logs.
where REDIS is for PUBSUB and DYNAMO DB is for storage for call logs. Notice that the diagram shows the simple flow for messaging where many flows are ignored to explain the basic flows.
Client <-> Server : Socket.io
Once one of client in a chatroom is not online, PUBSUB is not a good way to commnicate messages. So, the application server saves the message in Queue too using linked list. Then, once a client is back online, the message can be delivered to the client robustly.
The proposed architecture is using PUBSUB to endpoints which doesn't have the redundancy and some of benefits to notice the received message and manages a single connection for multiple chat rooms. Notice that see https://github.com/kyopark2014/webchat-golang-chat if you need more. Sender will publish to Receiver directly and messages can be delivered consistently without the state of Receiver.
As shown in the bellow picture, A will make a groupchat using a create event. Then IM server will save the participant list and subscribe the groupchat toward PUBSUB server. In this project, I will use a redis server for PUBSUB operation. The last participants execept owner will have an event which notices that "SUBSCRIBE" is required to get groupchat messages. After all of subscribe request were completed, the members in the groupchat can share messages easily based on PUBSUB.
This picture shows what relationship of client, IM and REDIS.
The basic groupchat flow is shown as bellow.
If one groupchat is not activate any more, it should be desubscribed in order to reduce resources. So, after the groupchat was deactivated, it can be activate when one of participants wants to send a message. But since there is no session based on PUBSUB machanism, it may not activate again. This picture shows how it reactivate.
OFFLINE -> ONLINE
This project shows the operation using docker.
$ docker run -d -p 8000:8000 amazon/dynamodb-local
$ docker run -d -p 6379:6379 redis:latest
- Profile Server
$ git clone https://github.com/kyopark2014/webchat-golang-profile
$ go run main.go
- Webchat server
$ git clone https://github.com/kyopark2014/webchat
$ go run main.go
- Run client
$ git clone https://github.com/kyopark2014/webchat-js-webclient
$ code
Note: I recommand "liver server" in visual studio code in order to run "index.html" in webchat-js-webclient
Note that the ip address in the server should be replaced from "localhost" to "your IP".
- Profile Server
$ git clone https://github.com/kyopark2014/webchat-golang-profile
$ go run main.go
- Webchat server
$ git clone https://github.com/kyopark2014/webchat
$ docker build -t webchat-golang-profile:v1 .
$ docker run -d -p 4040:4040 -e AWS_ACCESS_KEY="key" -e AWS_SECRET_ACCESS_KEY="key" webchat-golang-profile:v1
- Run client
$ git clone https://github.com/kyopark2014/webchat-js-webclient
$ docker build -t webclient:v1 .
$ docker run -d -p 8080:80 webclient:v1
- Open "http://ip-address:8080/ using chrome.