On this page
WebSockets and Real-Time
WebSockets provide full-duplex communication over a single TCP connection — ideal for chat, live feeds, and collaborative apps.
WebSocket vs HTTP
| HTTP | WebSocket |
|---|---|
| Request-response | Persistent connection |
| Client initiates | Both sides can send anytime |
| Headers on every request | Low overhead after handshake |
| Polling for updates | Push updates instantly |
Native WebSocket (ws package)
npm install ws
import { WebSocketServer } from 'ws';
const wss = new WebSocketServer({ port: 8080 });
wss.on('connection', (ws) => {
console.log('Client connected');
ws.send(JSON.stringify({ type: 'welcome', message: 'Hello!' }));
ws.on('message', (data) => {
const msg = JSON.parse(data);
// Broadcast to all clients
wss.clients.forEach(client => {
if (client.readyState === 1) { // OPEN
client.send(JSON.stringify(msg));
}
});
});
ws.on('close', () => console.log('Client disconnected'));
});
Socket.io (Recommended)
Handles reconnection, rooms, and fallbacks automatically:
npm install socket.io
Server:
import express from 'express';
import { createServer } from 'http';
import { Server } from 'socket.io';
const app = express();
const server = createServer(app);
const io = new Server(server, {
cors: { origin: 'http://localhost:5173' }
});
io.on('connection', (socket) => {
console.log('User connected:', socket.id);
socket.on('join-room', (roomId) => {
socket.join(roomId);
socket.to(roomId).emit('user-joined', socket.id);
});
socket.on('chat-message', ({ roomId, text, user }) => {
io.to(roomId).emit('chat-message', { text, user, time: Date.now() });
});
socket.on('disconnect', () => {
console.log('User disconnected:', socket.id);
});
});
server.listen(3000);
Client (browser):
import { io } from 'socket.io-client';
const socket = io('http://localhost:3000');
socket.emit('join-room', 'general');
socket.on('chat-message', (msg) => {
console.log(`${msg.user}: ${msg.text}`);
});
function sendMessage(text) {
socket.emit('chat-message', { roomId: 'general', text, user: 'Alice' });
}
Rooms and Namespaces
// Namespace for admin
const adminIo = io.of('/admin');
adminIo.on('connection', (socket) => {
// Admin-only events
});
// Rooms within a namespace
socket.join('room-123');
io.to('room-123').emit('update', data);
Scaling with Redis
For multiple server instances:
npm install @socket.io/redis-adapter redis
import { createAdapter } from '@socket.io/redis-adapter';
import { createClient } from 'redis';
const pubClient = createClient({ url: 'redis://localhost:6379' });
const subClient = pubClient.duplicate();
await Promise.all([pubClient.connect(), subClient.connect()]);
io.adapter(createAdapter(pubClient, subClient));
Use Cases
- Chat applications
- Live notifications
- Collaborative editing
- Real-time dashboards
- Online gaming
See the Real-Time Chat project for a full implementation guide.