A scalable WebSocket server implementation using Redis Pub/Sub for message distribution across multiple server instances. This architecture allows for horizontal scaling via kubernetes' horizontal pod auto-scaler while maintaining real-time message delivery across all connected clients.
-
WebSocket Server Layer
- Handles client connections
- Manages WebSocket lifecycle
- Routes messages to appropriate handlers
-
Redis Manager (Singleton)
- Manages Redis connections
- Handles Pub/Sub operations
- Ensures single Redis connection pool
-
Subscription Service
- Tracks active WebSocket connections
- Manages room subscriptions
- Handles message broadcasting
-
Message Flow
sequenceDiagram
Client->>WebSocket Server: Connect
WebSocket Server->>Subscription Service: Register Client
Client->>WebSocket Server: Subscribe to Room
WebSocket Server->>Redis: Subscribe to Channel
Client->>WebSocket Server: Send Message
WebSocket Server->>Redis: Publish Message
Redis->>WebSocket Server: Broadcast to Subscribers
WebSocket Server->>Client: Deliver Message
- Real-time bidirectional communication
- Horizontally scalable
- Redis-based message persistence
- Automatic reconnection handling
- Multiple room support
- TypeScript for type safety
- Clone the repository
git clone https://github.com/omkargade04/Scalable-Websocket-Server.git
cd Scalable-Websocket-Server
- Install dependencies
npm install
- Configure Redis
cd docker
docker-compose up -d
- Start the server
npm start
src/
├── managers/
│ └── RedisManager.ts # Redis connection management
├── services/
│ ├── WebSocketService.ts # WebSocket handling
│ └── SubService.ts # Subscription management
├── types/
│ └── types.ts # TypeScript interfaces
├── utils/
│ └── helper.ts # Utility functions
└── index.ts # Application entry point
const ws = new WebSocket('ws://localhost:8080');
ws.send(JSON.stringify({
type: 'SUBSCRIBE',
room: 'room1'
}));
ws.send(JSON.stringify({
type: 'SEND_MESSAGE',
roomId: 'room1',
message: 'Hello, World!'
}));
ws.send(JSON.stringify({
type: 'UNSUBSCRIBE',
room: 'room1'
}));
Type | Description | Payload |
---|---|---|
SUBSCRIBE | Join a room | { room: string } |
UNSUBSCRIBE | Leave a room | { room: string } |
SEND_MESSAGE | Send message to room | { roomId: string, message: string } |
The application can be scaled horizontally by running multiple instances behind a load balancer. Redis Pub/Sub ensures message delivery across all instances.
# Start multiple instances
PORT=8080 npm start
PORT=8081 npm start
PORT=8082 npm start
npm run dev
npm run build
class RedisManager {
// Get singleton instance
static getInstance(): RedisManager;
// Connect to Redis
connect(): Promise<void>;
// Publish message to channel
publish(channel: string, message: string): Promise<void>;
// Subscribe to channel
subscribe(channel: string, callback: (message: string) => void): Promise<void>;
// Unsubscribe to channel
unsubscribe(channel: string) => void): Promise<void>;
}
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature
) - Commit your changes (
git commit -m 'Add amazing feature'
) - Push to the branch (
git push origin feature/amazing-feature
) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details