Node.js WebSockets
WebSockets provide a full-duplex communication channel over a single, long-lived connection between a client and a server. Unlike HTTP, where the client always initiates requests and waits for a response, WebSockets allow both the client and the server to send messages to each other at any time — making them ideal for real-time applications.
Think of HTTP like sending letters back and forth — one side sends a letter, waits for a reply, then sends another. WebSockets are like a phone call — both sides can speak and listen simultaneously for as long as needed.
HTTP vs WebSockets
| Feature | HTTP | WebSocket |
|---|---|---|
| Connection | Opens and closes for each request | Stays open persistently |
| Direction | Client-to-server (request/response) | Bidirectional (both ways) |
| Real-time | Not suitable (polling needed) | Built for real-time |
| Overhead | Headers sent with every request | Minimal overhead after handshake |
| Use Cases | Fetching pages, REST APIs | Chat apps, live feeds, games |
Use Cases for WebSockets
- Real-time chat applications
- Live sports scores and news feeds
- Collaborative tools (like Google Docs)
- Multiplayer browser games
- Live financial dashboards and stock tickers
- Real-time notifications
Socket.IO – The Most Popular WebSocket Library for Node.js
Socket.IO is a library that builds on WebSockets and adds features like automatic reconnection, room management, broadcasting, and fallback to HTTP polling in environments where WebSockets are not available. It consists of two parts: a Node.js server library and a client-side JavaScript library.
Installing Socket.IO
npm install express socket.io
Building a Basic Real-Time Chat Application
Project Structure
chat-app/
├── app.js
├── public/
│ └── index.html
└── package.json
app.js – Server
const express = require('express');
const http = require('http');
const { Server } = require('socket.io');
const path = require('path');
const app = express();
const server = http.createServer(app); // Create HTTP server from Express app
const io = new Server(server); // Attach Socket.IO to the server
// Serve the HTML client file
app.use(express.static(path.join(__dirname, 'public')));
// Track connected users
let connectedUsers = 0;
// Handle WebSocket connections
io.on('connection', function(socket) {
connectedUsers++;
console.log(`User connected. Total users: ${connectedUsers}`);
// Notify all clients that someone joined
io.emit('user-joined', { count: connectedUsers });
// Listen for incoming chat messages from this client
socket.on('send-message', function(data) {
console.log('Message received:', data.message);
// Broadcast the message to ALL connected clients (including sender)
io.emit('receive-message', {
user: data.user,
message: data.message,
time: new Date().toLocaleTimeString()
});
});
// Handle disconnection
socket.on('disconnect', function() {
connectedUsers--;
console.log(`User disconnected. Total users: ${connectedUsers}`);
io.emit('user-left', { count: connectedUsers });
});
});
server.listen(3000, () => {
console.log('Chat server running at http://localhost:3000');
});
public/index.html – Client
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Real-Time Chat</title>
</head>
<body>
<h1>Real-Time Chat Room</h1>
<p id="user-count">Users online: 0</p>
<div id="messages"></div>
<input type="text" id="username" placeholder="Your name" />
<input type="text" id="message-input" placeholder="Type a message..." />
<button onclick="sendMessage()">Send</button>
<script src="/socket.io/socket.io.js"></script>
<script>
const socket = io();
// Display incoming messages
socket.on('receive-message', function(data) {
const messagesDiv = document.getElementById('messages');
const p = document.createElement('p');
p.textContent = `[${data.time}] ${data.user}: ${data.message}`;
messagesDiv.appendChild(p);
});
// Update user count
socket.on('user-joined', function(data) {
document.getElementById('user-count').textContent = 'Users online: ' + data.count;
});
socket.on('user-left', function(data) {
document.getElementById('user-count').textContent = 'Users online: ' + data.count;
});
// Send message to server
function sendMessage() {
const user = document.getElementById('username').value || 'Anonymous';
const message = document.getElementById('message-input').value;
if (message.trim()) {
socket.emit('send-message', { user, message });
document.getElementById('message-input').value = '';
}
}
</script>
</body>
</html>
Socket.IO Key Concepts
Emitting Events
// Emit to the current client only
socket.emit('eventName', data);
// Emit to ALL connected clients (including sender)
io.emit('eventName', data);
// Emit to ALL clients EXCEPT the sender
socket.broadcast.emit('eventName', data);
Rooms – Grouping Clients
Rooms allow messages to be sent only to specific groups of clients:
// Join a room
socket.join('room-name');
// Send a message to everyone in a specific room
io.to('room-name').emit('message', 'Hello to everyone in this room!');
// Leave a room
socket.leave('room-name');
Rooms are useful for building features like private chat channels or game lobbies.
Sending Data Back to the Sender Only
io.on('connection', function(socket) {
socket.emit('welcome', { message: 'You are connected!' });
});
Handling Disconnections Gracefully
io.on('connection', function(socket) {
const userId = socket.id;
console.log('Connected:', userId);
socket.on('disconnect', function(reason) {
console.log(`User ${userId} disconnected. Reason: ${reason}`);
});
});
Key Points
- WebSockets provide a persistent, full-duplex connection — both client and server can send messages at any time.
- HTTP is request-response (client initiates); WebSockets are bidirectional (either side can initiate).
- Socket.IO is the most popular WebSocket library for Node.js. It adds reconnection, rooms, and broadcasting features.
- Socket.IO requires creating an HTTP server from Express first, then attaching Socket.IO to it.
socket.emit()sends to one client;io.emit()sends to all;socket.broadcast.emit()sends to all except the sender.- Rooms allow messages to be scoped to a group of clients — essential for building chat channels or game lobbies.
- Always handle the
'disconnect'event to clean up user state when a client leaves.
