The limit of HTTP
HTTP is request-response: the client asks and the server answers. The server cannot speak first. For a chat or a live dashboard that is a problem: how does the server tell the browser that a new message has arrived?
The classic solution is polling: the client asks every few seconds "is there anything new?". It works, but it wastes requests (almost always the answer is "no") and adds latency (up to several seconds of delay).
WebSockets
A WebSocket opens a persistent and bidirectional connection between client and server over a single TCP connection. Once open, both sides can send data at any time, without asking for permission again.
// In the browser
const socket = io(); // opens the connection
socket.on("message", (m) => { // listens for events from the server
console.log("Arrived:", m);
});
socket.emit("send", "Hi"); // emits an event to the server
Socket.io is the most used library in Node for this. Its model is based on
named events: emit("name", data) sends and on("name", cb)
listens. It is the same publisher/subscriber pattern you already know from
Node's EventEmitter.
// On the server
io.on("connection", (socket) => {
socket.on("send", (text) => {
io.emit("message", text); // forwards to everyone connected
});
});
Rooms
A room groups connections to emit only to a subset. Useful for chat channels, matches or a specific user:
socket.join("room-42"); // the socket enters the room
io.to("room-42").emit("message", text); // only those in that room receive it
Use cases
- Chat and instant messaging.
- Push notifications in the app itself.
- Live dashboards (quotes, metrics, scoreboards).
- Real-time collaboration (editing a document among several people).