WebSockets have revolutionized real-time communication on the web, enabling instant data exchange between clients and servers. Whether you’re building a chat app, live dashboard, multiplayer game, or real-time notification system — WebSockets are your go-to tool.
In this blog, we’ll go deep into how to work with WebSockets in Node.js, covering:
- What are WebSockets?
- When to use them
- How they work
- WebSocket vs HTTP
- Implementing WebSockets in Node.js with
ws
- Using WebSockets with Express
- Broadcasting messages
- Handling errors and disconnections
- Advanced tips & scalability ideas
Let’s dive in!
What are WebSockets?
WebSockets are a communication protocol that provides full-duplex (two-way) communication channels over a single TCP connection. Unlike HTTP, which follows a request-response model, WebSockets allow the server to push data to the client without being asked first.
Key Benefits:
- Low latency
- Lightweight (no headers like HTTP)
- Real-time communication
- Bidirectional connection
When Should You Use WebSockets?
Choose WebSockets when:
- You need real-time updates (chat, live feed, multiplayer game)
- Frequent server push is needed (like notifications)
- Polling with HTTP is inefficient
Avoid WebSockets if:
- Your use case is purely request-response (e.g., REST APIs)
- You don’t need persistent connections
How WebSockets Work
- Client sends a WebSocket handshake request
- Server responds with a handshake response
- The connection is established
- Both client and server can now send messages any time
- Either side can terminate the connection
The entire process uses the same ports as HTTP:
- ws:// (non-secure) → port 80
- wss:// (secure, like HTTPS) → port 443
Setting Up WebSockets in Node.js
We’ll use the popular ws
library.
Step 1: Install ws
npm init -y
npm install ws
Basic WebSocket Server with Node.js
const WebSocket = require('ws');
const server = new WebSocket.Server({ port: 8080 });
server.on('connection', (socket) => {
console.log('Client connected.');
socket.on('message', (message) => {
console.log(`Received: ${message}`);
socket.send(`You said: ${message}`);
});
socket.on('close', () => {
console.log('Client disconnected.');
});
});
WebSocket Client (HTML)
<!DOCTYPE html>
<html>
<body>
<input id="messageInput" />
<button onclick="sendMessage()">Send</button>
<ul id="messages"></ul>
<script>
const socket = new WebSocket('ws://localhost:8080');
socket.onmessage = function (event) {
const li = document.createElement('li');
li.textContent = `Server: ${event.data}`;
document.getElementById('messages').appendChild(li);
};
function sendMessage() {
const input = document.getElementById('messageInput');
socket.send(input.value);
input.value = '';
}
</script>
</body>
</html>
Using WebSockets with Express
You can also integrate WebSockets with an existing Express app.
jsCopyEditconst express = require('express');
const http = require('http');
const WebSocket = require('ws');
const app = express();
const server = http.createServer(app);
const wss = new WebSocket.Server({ server });
wss.on('connection', function connection(ws) {
console.log('A new client connected.');
ws.on('message', function incoming(message) {
console.log('received: %s', message);
ws.send(`Hello from server, you said: ${message}`);
});
});
app.get('/', (req, res) => {
res.sendFile(__dirname + '/index.html');
});
server.listen(8080, () => {
console.log('Server is listening on http://localhost:8080');
});
Broadcasting Messages to All Clients
wss.on('connection', function connection(ws) {
ws.on('message', function incoming(message) {
// Broadcast to all
wss.clients.forEach(function each(client) {
if (client.readyState === WebSocket.OPEN) {
client.send(`Broadcast: ${message}`);
}
});
});
});
🛠 Handling Disconnections and Errors
ws.on('close', () => {
console.log('Client has disconnected.');
});
ws.on('error', (error) => {
console.error('WebSocket error:', error);
});
Advanced Tips
1. Ping/Pong Heartbeat
WebSockets don’t automatically detect dead connections. Implement a heartbeat:
function heartbeat() {
this.isAlive = true;
}
wss.on('connection', function (ws) {
ws.isAlive = true;
ws.on('pong', heartbeat);
});
const interval = setInterval(() => {
wss.clients.forEach((ws) => {
if (ws.isAlive === false) return ws.terminate();
ws.isAlive = false;
ws.ping();
});
}, 30000);
2. Authentication via Query Params or Headers
Use token-based authentication like:
const url = require('url');
wss.on('connection', function connection(ws, req) {
const params = url.parse(req.url, true);
const token = params.query.token;
// Validate token here
});
3. Scaling with Redis Pub/Sub
If you deploy your app across multiple Node.js instances (like on PM2 or Docker), you’ll need a central messaging system like Redis Pub/Sub to sync messages across servers.
Debugging WebSocket Connections
Use browser DevTools:
- Network tab → WS → Inspect Frames
Or use CLI tools:
wscat
– A WebSocket CLI client bashCopyEditnpm install -g wscat wscat -c ws://localhost:8080
WebSockets vs Other Real-Time Technologies
Tech | Use Case | Pros | Cons |
---|---|---|---|
WebSocket | Real-time, bidirectional comm | Fast, low-latency | Requires persistent conn |
HTTP Polling | Basic real-time, easy to implement | Simple | Wasteful & high latency |
Server-Sent Events (SSE) | Server → Client only | Simpler than WS for one-way | No client → server comm |
Socket.IO | Wrapper over WebSockets + fallback | Easier API, fallback support | Slightly heavier than ws |
Popular Libraries
ws
– Lightweight and efficientsocket.io
– Easy-to-use abstraction with fallback supportuWebSockets.js
– Extremely fast
Final Thoughts
WebSockets are a powerful tool in modern web development, allowing truly real-time, low-latency communication between clients and servers. Node.js, being event-driven and asynchronous by design, is an excellent environment to implement them.
By following this guide, you can:
- Create a WebSocket server
- Connect from a browser client
- Handle messages, errors, and disconnections
- Scale and secure your WebSocket app
Ready to Build Real-Time Apps?
Here are some project ideas:
- Live chat room
- Real-time trading dashboard
- Online multiplayer board game
- Collaborative document editor
If you want the source code from this blog as a GitHub project, just let me know!
Share Your Feedback
Did you find this blog helpful? Want to see more real-time topics or integrations with frameworks like React, Next.js, or NestJS?
Comment below or message us directly. Let’s keep learning together.