To implement WebSockets with Redis Pub/Sub for scalable, real-time communication across multiple servers, here’s a step-by-step example that combines WebSockets and Redis.
- WebSocket: Handles real-time communication between clients and the server.
- Redis Pub/Sub: Allows the server to broadcast messages to all connected WebSocket clients, even when there are multiple instances of the server.
First, you need to install the required packages:
npm install express ws redis
express
: For setting up the web server.ws
: For WebSocket handling.redis
: For Redis Pub/Sub integration.
Store your Redis configuration in a .env
file:
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_CHANNEL=chat_channel
PORT=3000
Now, let’s set up the WebSocket server along with Redis Pub/Sub integration:
require("dotenv").config();
const express = require("express");
const WebSocket = require("ws");
const redis = require("redis");
const app = express();
const server = app.listen(process.env.PORT || 3000, () => {
console.log(`🚀 Server running on http://localhost:${process.env.PORT || 3000}`);
});
// Set up WebSocket server
const wss = new WebSocket.Server({ server });
// Redis setup (Publisher)
const redisClient = redis.createClient({
host: process.env.REDIS_HOST,
port: process.env.REDIS_PORT,
});
// Redis setup (Subscriber)
const redisSubscriber = redis.createClient({
host: process.env.REDIS_HOST,
port: process.env.REDIS_PORT,
});
// Listen to Redis Pub/Sub channel
redisSubscriber.subscribe(process.env.REDIS_CHANNEL);
// Handle WebSocket connections
wss.on("connection", (ws) => {
console.log("✅ New WebSocket client connected.");
// Listen for incoming WebSocket messages and publish them to Redis
ws.on("message", (message) => {
console.log("📩 Message received from WebSocket client:", message);
// Publish the message to Redis channel
redisClient.publish(process.env.REDIS_CHANNEL, message);
});
// Send a welcome message to the WebSocket client
ws.send(JSON.stringify({ message: "Welcome to the WebSocket server!" }));
// Handle WebSocket errors
ws.on("error", (error) => {
console.error("❌ WebSocket error:", error);
});
});
// Handle Redis messages and broadcast them to all connected WebSocket clients
redisSubscriber.on("message", (channel, message) => {
console.log(`📡 New message on Redis channel '${channel}':`, message);
// Broadcast the message to all connected WebSocket clients
wss.clients.forEach((client) => {
if (client.readyState === WebSocket.OPEN) {
client.send(message);
}
});
});
console.log("✅ Redis Pub/Sub is set up.");
Create a simple HTML page that connects to the WebSocket server and listens for messages:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>WebSocket Chat</title>
</head>
<body>
<h1>WebSocket Chat</h1>
<div id="messages"></div>
<input type="text" id="messageInput" placeholder="Type a message..." />
<button id="sendButton">Send</button>
<script>
const socket = new WebSocket("ws://localhost:3000");
const messagesDiv = document.getElementById("messages");
const messageInput = document.getElementById("messageInput");
const sendButton = document.getElementById("sendButton");
// On connection open, show welcome message
socket.onopen = () => {
console.log("✅ WebSocket connection established.");
};
// Listen for incoming WebSocket messages
socket.onmessage = (event) => {
const data = JSON.parse(event.data);
const messageElement = document.createElement("p");
messageElement.textContent = data.message;
messagesDiv.appendChild(messageElement);
};
// Send a message when the user clicks "Send"
sendButton.addEventListener("click", () => {
const message = messageInput.value;
if (message) {
socket.send(message);
messageInput.value = ""; // Clear input
}
});
// Handle WebSocket errors
socket.onerror = (error) => {
console.error("❌ WebSocket error:", error);
};
</script>
</body>
</html>
Make sure Redis is running:
docker run -d --name redis -p 6379:6379 redis
If you don’t have Redis installed, you can use Docker to run it or install it locally.
To run the WebSocket server:
node server.js
- Open the Frontend:
Open
index.html
in your browser. - Test Messaging: Type a message and click Send. Your message will be sent to the WebSocket server and broadcast to all connected clients through Redis Pub/Sub.
- WebSocket Server: Handles real-time communication with the clients.
- Redis Pub/Sub:
- The publisher (in the WebSocket server) sends messages to a Redis channel.
- The subscriber (also in the WebSocket server) listens for messages on the Redis channel and broadcasts them to all WebSocket clients.
- Scaling: With this setup, even if the server is scaled across multiple instances, Redis Pub/Sub ensures that all instances can publish and subscribe to the same channel, making the system scalable.
This setup is highly scalable and can handle massive-scale real-time events using WebSockets combined with Redis Pub/Sub. The WebSocket server and clients can send and receive real-time messages, while Redis ensures messages are broadcast across multiple instances of the WebSocket server. This approach is ideal for building chat apps, live notifications, and any other event-driven systems.
Let me know if you'd like more improvements or explanations! 🚀