How to integrate WebSocket with Express.js?
WebSocket in Express.js
WebSocket provides full-duplex, persistent connections between client and server. Unlike HTTP (request-response), WebSocket allows the server to push data to clients in real-time.
HTTP vs WebSocket
| Feature | HTTP | WebSocket |
|---|---|---|
| Connection | New for each request | Persistent |
| Direction | Client → Server | Bidirectional |
| Protocol | http:// / https:// | ws:// / wss:// |
| Overhead | Headers on every request | Minimal after handshake |
| Use case | REST APIs, pages | Real-time: chat, notifications, games |
Using Socket.IO (Most Popular)
bash
npm install socket.ioServer Setup
js
const express = require('express');
const http = require('http');
const { Server } = require('socket.io');
const app = express();
const server = http.createServer(app);
const io = new Server(server, {
cors: {
origin: 'http://localhost:3000',
methods: ['GET', 'POST']
}
});
io.on('connection', (socket) => {
console.log('User connected:', socket.id);
// Listen for events
socket.on('chat:message', (data) => {
// Broadcast to all except sender
socket.broadcast.emit('chat:message', {
user: data.user,
text: data.text,
timestamp: new Date()
});
});
// Join a room
socket.on('room:join', (roomId) => {
socket.join(roomId);
io.to(roomId).emit('room:userJoined', socket.id);
});
socket.on('disconnect', () => {
console.log('User disconnected:', socket.id);
});
});
// Express routes still work normally
app.get('/api/health', (req, res) => res.json({ status: 'ok' }));
server.listen(4000, () => console.log('Server on port 4000'));Client
js
import { io } from 'socket.io-client';
const socket = io('http://localhost:4000');
socket.on('connect', () => {
console.log('Connected:', socket.id);
});
socket.emit('chat:message', { user: 'John', text: 'Hello!' });
socket.on('chat:message', (data) => {
console.log(`${data.user}: ${data.text}`);
});Using Native ws Library (Lightweight)
bash
npm install wsjs
const express = require('express');
const { WebSocketServer } = require('ws');
const app = express();
const server = app.listen(4000);
const wss = new WebSocketServer({ server });
wss.on('connection', (ws) => {
ws.on('message', (message) => {
const data = JSON.parse(message);
// Broadcast to all connected clients
wss.clients.forEach((client) => {
if (client.readyState === 1) {
client.send(JSON.stringify(data));
}
});
});
});Rooms and Namespaces (Socket.IO)
js
// Namespace for admin panel
const adminIO = io.of('/admin');
adminIO.on('connection', (socket) => {
// Only admin events here
socket.on('admin:action', handleAdminAction);
});
// Rooms within default namespace
io.on('connection', (socket) => {
socket.on('joinRoom', (roomId) => {
socket.join(roomId);
});
socket.on('message', (data) => {
io.to(data.roomId).emit('message', data);
});
});Authentication
js
io.use((socket, next) => {
const token = socket.handshake.auth.token;
try {
const user = jwt.verify(token, process.env.JWT_SECRET);
socket.user = user;
next();
} catch (err) {
next(new Error('Authentication error'));
}
});Socket.IO vs ws
| Feature | Socket.IO | ws |
|---|---|---|
| Size | ~50KB | ~3KB |
| Rooms | Built-in | Manual |
| Fallback | HTTP polling | WebSocket only |
| Auto-reconnect | Built-in | Manual |
| Namespaces | Built-in | No |
| Binary | Yes | Yes |
Tip: Use Socket.IO for complex real-time apps (chat, collaboration, notifications). Use ws for simple, low-overhead WebSocket connections. Both can coexist with Express routes on the same server.
Short Answer
Interview readyPremium
A concise answer to help you respond confidently on this topic during an interview.