Build A Go Real-Time Chat Application With MySQL, RabbitMQ And Websockets
I was recently tasked to build an application that allows several users to talk in one or more chatrooms and also to get stock quotes from an external API using a specific command. For this task, I utilised microservices, RabbitMQ as the message broker of choice, MySQL for persisting data, and websockets with Golang. The application also has other features and they are as follows:
- Allow registered users to login and talk with other users in a chatroom.
- Allow users to post messages as commands into the chatroom with the following format /stock=stock_code
- Create a “decoupled” bot that will call an API using the stock_code as a parameter
(https://stooq.com/q/l/?s=aapl.us&f=sd2t2ohlcv&h&e=csv, here “aapl.us” is the stock_code)
- The bot should parse the received CSV file and then it should send a message back into the chatroom using a message broker like RabbitMQ. The message will be a stock quote using the following format: “APPL.US quote is $93.42 per share”. The post owner will be the bot.
The aim of this blog post is to explain the microservices architecture I used for developing the application. To make it easily digestible, I won’t be sharing code snippets, however, if you’d rather skip this tutorial and go straight to the code, the links to the repositories are in the Source code section and you can find it at the end of the post.
As earlier stated, I used microservices for this task. A Microservices Architecture consists of a collection of small, autonomous services. Each service is usually self-contained and should implement a business capability. The three microservices I used to accomplish this task are
- Chat service
- Bot service
- React Frontend service
The chat and bot services were built with Go(golang) and you can get the link to the repositories at the end of the post. The diagram below is the microservices architecture I used and when you study the diagram , you’ll notice that each of these services can be scaled individually. I also used the nested box diagram to illustrate an application having multiple instances.
One major issue microservices encounter is in the communication between services. There are a couple examples of how they can communicate: REST APIs, gRPC, message brokers like RabbitMQ or Kafka. For this exercise, I used RabbitMQ to communicate between the Bot service and the Chat service and I used REST APIs to communicate between the React frontend service and the Chat Service.
The diagram above describes how the Chat service functions. The Chat service is the main entry point for the application’s usage as it houses the REST endpoints for authentication, creating the rooms for chats, and fetching persisted chats. I also setup Websockets in it to achieve real-time communication with the React frontend application.
The app’s requirement is that we should be able to make stock requests and we handle this by first sending a request from the chat room. The chat service can check the structure of a message and whenever it sees a /stock=stock_code format, it knows that it should pass the request to the bot service. I set up RabbitMQ to encapsulate how the request is sent to the bot service.
To ease communication, I set up RabbitMQ to have two queues. One for receiving requests and the other for publishing the results of received requests, then I set up the chat service to listen on the publisher queue as it will contain the resolved requests and send stock requests to the receiver queue.
Likewise, the bot service listens to the Receiver queue and calls the 3rd party stock information service to get the data for a stock code. The 3rd party service returns a CSV file that is then processed by the bot service and passed to the chat service via the publisher queue.
It was interesting building this application and I hope that my explanation simplified the complexity of building this type of application. I’m available to answer questions so feel free to ask.
Chat service : Realtime chat backend powered with Websockets and RabbitMQ
Repo Link: https://github.com/ong-gtp/go-chat
Bot service : A decoupled bot service that communicates with the chat backend with RabbitMQ
Repo Link : https://github.com/ong-gtp/go-stockbot-rabbitmq.git
React Frontend : The frontend application that allows registered users to log in and talk with other users in a chatroom
Repo Link : https://github.com/ong-gtp/go-chat-react.git