WebSocket Heartbeats — Complete Guide
In this tutorial, you will learn about WebSocket Heartbeats. We cover key concepts, practical examples, and best practices to help you master this topic.
WebSocket heartbeats use ping and pong frames to check connection health. The server sends periodic pings, and clients respond with pongs. Missing pongs indicate a dead connection that should be terminated and reconnected.
What You'll Learn
- Ping-pong frame mechanism
- Server-side heartbeat implementation
- Client-side heartbeat handling
- Heartbeat intervals and timeouts
- Proxy and load balancer timeout considerations
Why It Matters
Network devices (proxies, load balancers) drop idle connections. Heartbeats keep connections alive and detect silent disconnections. Without heartbeats, zombie connections accumulate and waste resources.
Real-World Use
AWS ALB times out idle connections after 60 seconds. Cloudflare waits 60-90 seconds. Heartbeats at 30-second intervals prevent these timeouts and provide early failure detection.
sequenceDiagram
Server->>Client: WebSocket Ping
Client-->>Server: WebSocket Pong
Note over Server: Wait pingInterval
Server->>Client: WebSocket Ping
Note over Client: Client lost network
Server->>Client: WebSocket Ping
Note over Server: pingTimeout expired
Server->>Server: Close connection
Teacher Mindset
Heartbeats are essential for production WebSocket servers. Set ping intervals shorter than your proxy timeout. Set ping timeout to 2-3x the interval. Always handle pong responses to confirm client liveness.
Code Examples
// Example 1: Server-side heartbeat with ws library
const WebSocket = require('ws');
const server = new WebSocket.Server({
port: 8080,
pingInterval: 30000,
pingTimeout: 5000
});
server.on('connection', (ws) => {
console.log('Client connected');
ws.on('pong', () => {
console.log('Received pong from client');
ws.isAlive = true;
});
ws.on('close', () => {
console.log('Client disconnected');
});
});
// Heartbeat check interval
const heartbeat = setInterval(() => {
server.clients.forEach((ws) => {
if (ws.isAlive === false) {
console.log('Terminating dead connection');
return ws.terminate();
}
ws.isAlive = false;
ws.ping();
});
}, 30000);
server.on('close', () => clearInterval(heartbeat));
// Example 2: Client-side heartbeat handler
const ws = new WebSocket('ws://localhost:8080');
ws.on('open', () => {
console.log('Connected');
});
ws.on('ping', () => {
// Automatically sends pong in the ws library
console.log('Received ping, sending pong');
});
ws.on('close', () => {
console.log('Connection closed by server heartbeat');
});
// Example 3: Socket.IO with heartbeat configuration
const io = require('socket.io')(3000, {
pingInterval: 25000,
pingTimeout: 20000
});
io.on('connection', (socket) => {
console.log('Client connected');
socket.on('disconnect', (reason) => {
console.log('Disconnected:', reason);
// "ping timeout" means heartbeat failed
});
});
Common Mistakes
- Setting ping interval longer than proxy/load balancer timeout
- Not checking the pong response before terminating connections
- Sending pings too frequently, generating unnecessary traffic
- Not handling the ping event on the client side
- Forgetting that Socket.IO has built-in ping-pong (configure pingInterval)
Practice
- Implement server-side heartbeat with 30s interval and 10s timeout.
- Verify that clients respond to pings with pongs.
- Simulate a network drop and verify the server terminates the connection.
- Configure Socket.IO heartbeat with custom intervals.
- Challenge: Build a heartbeat monitoring dashboard that shows alive/dead connection counts.
FAQ
Mini Project
Configure heartbeats on your WebSocket server with 25s ping interval and 10s timeout. Add a connection health monitor that logs alive connections count every 30 seconds. Test that connections are terminated after 10 seconds without pong.
What's Next
Next, you will learn about integrating WebSocket with Express.js"Express" >}}.js.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro