A real-time chat application demonstrating WebSocket connections distributed across multiple Node.js instances using RabbitMQ and Nginx.
Client 1 Client 2
\ /
\ /
v v
[ Nginx Proxy ] (Load Balancer)
/ \
v v
[ App Node 1 ] [ App Node 2 ] (WebSocket Servers)
\ /
\ /
v v
[ RabbitMQ ] (Message Broker / Fanout Exchange)
- Nginx: Serves the static HTML/JS client and proxies
/wsrequests to the upstream Node.js servers, load-balancing connections (round-robin). - WebSockets: Maintains an open, real-time connection between the browser and a specific Node.js server instance.
- RabbitMQ: The Node.js instances publish incoming chat messages to a RabbitMQ fanout exchange. Each instance has an exclusive queue bound to this exchange. When a message is received from the queue, the instance broadcasts it to all its locally connected WebSocket clients. This ensures messages sent to one node are distributed to clients on all other nodes.
- Make sure you have Docker and Docker Compose installed.
- Run the following command in this directory:
docker compose up --build
- Open
http://localhost:8090in your browser.
- Open
http://localhost:8090in two different browser tabs. - Enter a different username in each tab and connect.
- Check the chat window to see which Server ID (
[node-1]or[node-2]) each client is connected to. - Send messages between the tabs. You will see messages seamlessly delivered across nodes.
- Stop one of the application nodes (e.g.,
docker stop two-node-chat-app1-1). - The client connected to the stopped node will automatically reconnect (after a 2-second delay) to the surviving node, and you can continue chatting without losing the ability to send messages.