Complete "Broadcasting Events and Integrating with a REST API" first to unlock this lesson.Go to previous lesson

Introduction

Socket.IO is a library built on top of the WebSocket protocol that adds developer-friendly features not available in raw WebSockets. When building real-time features like chat apps, collaborative editors, or live dashboards, you often need to group clients logically, isolate communication channels, and handle dropped connections gracefully. Socket.IO provides rooms, namespaces, auto-reconnect, and transport fallback out of the box, so you do not have to engineer these from scratch.

This lesson walks through each of these four features with concrete code. By the end you will know how to segment your server into namespaces, dynamically group sockets into rooms, let clients reconnect automatically, and rely on HTTP long-polling as a safety net when WebSockets are blocked.

Namespaces

A namespace is a separate communication channel that shares the same underlying TCP connection. The default namespace is `/`, but you can create custom ones to logically separate concerns — for example a public chat versus an admin control panel.

On the server:

javascript
const io = require('socket.io')(3000);
const adminNamespace = io.of('/admin');
adminNamespace.on('connection', (socket) => {
console.log('Admin connected:', socket.id);
});

On the client:

javascript
const adminSocket = io('/admin');
adminSocket.emit('admin-login', { user: 'alice' });

Anything sent through the `/admin` namespace stays isolated from the default `/` namespace, even though both run on the same server and port.

Rooms

Rooms are sub-channels inside a namespace. A socket can join or leave a room at any time, and the server can broadcast to every socket in a room with one call. This is the pattern you want for per-conversation messaging in a chat app or per-game-room state in a multiplayer game.

javascript
io.on('connection', (socket) => {
socket.on('join-room', (roomId) => {
socket.join(roomId);
socket.to(roomId).emit('user-joined', socket.id);
});
socket.on('chat-message', ({ roomId, message }) => {
io.to(roomId).emit('chat-message', { from: socket.id, message });
});
socket.on('disconnect', () => {
console.log('Socket left:', socket.id);
});
});

`socket.join(roomId)` adds the socket to an in-memory set maintained by Socket.IO. `io.to(roomId).emit(...)` then delivers the payload to every member of that room. The joining socket itself does not receive messages sent with `socket.to(...)` — use that when you want to notify "everyone else" in the room.

sơ đồ 1 namespace chứa 3 phòng, mỗi phòng có vài client, mũi tên broadcast từ server đến từng phòng

Auto-Reconnect and Transport Fallback

Raw WebSockets stop working permanently the moment the network drops. Socket.IO's client handles reconnection automatically. You can configure the retry strategy and tell the user what is happening through events.

javascript
const socket = io({
reconnection: true,
reconnectionAttempts: 10,
reconnectionDelay: 1000,
reconnectionDelayMax: 5000,
});
socket.on('reconnect_attempt', (attempt) => {
console.log('Trying to reconnect, attempt', attempt);
});
socket.on('reconnect', (attemptNumber) => {
console.log('Reconnected after', attemptNumber, 'tries');
});
socket.on('connect_error', (err) => {
console.log('Connection failed:', err.message);
});

Transport fallback is the other half of resilience. Socket.IO always tries WebSocket first because it is the lowest-latency option, but if the handshake fails — corporate firewalls, old proxies, restrictive networks — it silently falls back to HTTP long-polling. The application code does not change; your `emit` and `on` calls work identically over either transport.

Common Pitfalls and Summary

Two mistakes come up often. First, do not store room membership in your own variable — always trust `socket.rooms` returned by Socket.IO, because the library manages join and leave internally and your cache will drift. Second, remember that `socket.to(roomId)` excludes the sender while `io.to(roomId)` includes them, so pick the right one for your broadcast intent.

To summarize: namespaces split your server into isolated channels, rooms group sockets inside a namespace for targeted broadcasts, auto-reconnect recovers from dropped networks without code changes, and transport fallback keeps you online even when WebSockets are blocked. Together these features remove the boilerplate you would otherwise write on top of raw WebSockets.

Lesson practice

Lesson Checkpoint

Review what you learned and get feedback on your work.

0/1
Answered · 0/1