Scaling WebSocket ServersLesson 6.2
How to use Redis pub/sub to broadcast across WebSocket servers
Redis pub/sub model, PUBLISH and SUBSCRIBE commands, channel naming, ioredis client, publish on message receive, subscribe and forward pattern, serialization overhead
Redis as the Cross-Server Message Bus
Each server instance publishes incoming messages to Redis. All instances subscribe and forward messages to their local sockets:
const Redis = require('ioredis');
const pub = new Redis();
const sub = new Redis();
const CHANNEL = 'chat:global';
// Subscribe on startup
sub.subscribe(CHANNEL);
sub.on('message', (channel, rawMsg) => {
const msg = JSON.parse(rawMsg);
// Forward to all LOCAL clients
for (const client of wss.clients) {
if (client.readyState === WebSocket.OPEN) {
client.send(rawMsg); // already serialized
}
}
});
// When a client sends a message, publish to Redis
ws.on('message', (data) => {
const msg = JSON.parse(data);
pub.publish(CHANNEL, JSON.stringify({
...msg,
originServer: process.env.SERVER_ID
}));
});Add an originServer field so each server can skip re-delivering to the sender if they are on the same instance. Use per-room channels (chat:room:roomId) to avoid every server processing every message - subscribe only to rooms that have local clients.
