In this lesson, you will learn how to scale your WebSocket architecture by using Redis Pub/Sub to synchronize messages across multiple server instances.
The Problem: Horizontal Scaling
When you run a single Node.js instance, tracking WebSocket connections is easy: you hold them in an in-memory array or a Map. However, as your application grows, you will deploy multiple server instances behind a load balancer. If User A is connected to Server 1 and User B is connected to Server 2, Server 1 has no knowledge of User B. If User A sends a message intended for User B, the broadcast will fail because the servers are isolated.
The Solution: The Redis Bridge
We solve this by introducing a Redis Pub/Sub layer. Instead of broadcasting directly to local sockets, each server instance "subscribes" to a Redis channel.
- When a message arrives at Server 1, it publishes that message to a Redis channel.
- Every other server instance (including Server 2) is subscribed to that channel and receives the message instantly via Redis.
- Once received from Redis, the local server broadcasts that message to its own locally-connected clients.
Concrete Implementation
Here is how you might structure the listener in your WebSocket factory:
const redis = require('redis');
const pub = redis.createClient();
const sub = redis.createClient();
// Listen for messages from other server instances
sub.subscribe('CHAT_CHANNEL');
sub.on('message', (channel, message) => {
const data = JSON.parse(message);
// Broadcast to all clients connected to THIS specific instance
webSocketServer.clients.forEach(client => {
if (client.readyState === WebSocket.OPEN) {
client.send(JSON.stringify(data));
}
});
});
// When a local client sends a message, publish to Redis
socket.on('message', (msg) => {
pub.publish('CHAT_CHANNEL', msg);
});
By decoupling the source of the message from the delivery of the message, you ensure that your WebSocket events propagate across your entire infrastructure, making your application truly horizontally scalable.
Key Takeaway: Redis acts as a global message bus that allows isolated WebSocket servers to communicate, ensuring that broadcasts reach clients regardless of which server instance they are currently connected to.