Broadcasting Basics
While socket.emit() targets one specific client, Socket.IO provides several ways to reach many clients at once. io.emit('eventName', data) sends the event to every currently connected client on the server, including whichever client might have triggered the action. socket.broadcast.emit('eventName', data) sends to every connected client except the sender's own socket — the common pattern for 'someone else did something' notifications like 'user X joined the chat', where the acting user doesn't need to see their own join message echoed back.
Cricket analogy: It's like the stadium PA announcing 'four runs!' to every single spectator including the batter's own family in the stands (io.emit), versus a scoreboard update visible to everyone in the ground except the scorer's own booth (broadcast.emit).
Rooms
Broadcasting to literally everyone is rarely what real applications need — a chat app with 10,000 users shouldn't blast every message to every connection. Socket.IO's room system solves this: socket.join('room-42') subscribes a socket to an arbitrary named channel (rooms are created implicitly the first time a socket joins them and destroyed automatically once empty), and io.to('room-42').emit('eventName', data) sends the event only to sockets currently in that room. A socket can join multiple rooms simultaneously, and rooms are entirely server-side constructs — clients have no visibility into which rooms exist or who else is in them unless the server explicitly tells them via emitted data.
Cricket analogy: It's like IPL franchise WhatsApp groups — joining the 'Mumbai Indians fans' room only routes match commentary relevant to MI, not every match happening across the tournament, and you can be in the MI room and a fantasy-league room at once.
Combining broadcast and rooms
These mechanisms compose: socket.to('room-42').emit(...) sends to everyone in room-42 except the sender, combining room-scoping with the broadcast-except-self pattern — this is the exact call used for 'user is typing' indicators in a chat room. You can also target multiple rooms at once with io.to('room-a').to('room-b').emit(...) (a client in either room receives it once, even if in both), and exclude specific rooms with .except('room-c'). Leaving is symmetric: socket.leave('room-42') removes the socket, and Socket.IO automatically calls leave for all rooms a socket was in when it disconnects.
Cricket analogy: It's like a captain's mic message going to every fielder in the 'inner circle' room except the bowler who's mid-run-up (socket.to().emit), useful for field-adjustment calls that shouldn't distract the bowler themselves.
io.on('connection', (socket) => {
socket.on('join room', (roomId) => {
socket.join(roomId);
// tell everyone else in the room, not the joiner
socket.to(roomId).emit('user joined', { id: socket.id });
});
socket.on('typing', (roomId) => {
socket.to(roomId).emit('user typing', { id: socket.id });
});
socket.on('chat message', ({ roomId, text }) => {
// everyone in the room, including the sender, sees their own message echoed
io.to(roomId).emit('chat message', { id: socket.id, text });
});
socket.on('leave room', (roomId) => {
socket.leave(roomId);
});
});Every socket automatically joins a default room named after its own socket.id when it connects — this is what makes socket.emit() (send to just this client) possible internally, since it's effectively io.to(socket.id).emit() under the hood.
Rooms are per-server-process by default. If you scale to multiple Node.js instances behind a load balancer, io.to(room).emit() on one instance won't reach sockets connected to a different instance unless you configure an adapter (e.g. the Redis adapter) that synchronizes room membership and broadcasts across all instances.
- io.emit() sends to every connected client, including the triggering client.
- socket.broadcast.emit() sends to every client except the sender's own socket.
- socket.join(room) and socket.leave(room) manage arbitrary server-side room membership.
- io.to(room).emit() sends only to sockets currently in that room.
- socket.to(room).emit() combines room-scoping with excluding the sender.
- Every socket automatically belongs to a default room named for its own socket.id.
- Multi-instance deployments need an adapter (e.g. Redis) for rooms to work across servers.
Practice what you learned
1. Which call sends an event to every connected client, including the one that triggered it?
2. What is the effect of socket.broadcast.emit('event', data)?
3. How are Socket.IO rooms created?
4. What does socket.to('room-42').emit('event', data) do?
5. Why is an adapter like the Redis adapter needed when scaling Socket.IO across multiple server instances?
Was this page helpful?
You May Also Like
Emitting and Listening to Events
Learn how Socket.IO's event-based API lets clients and servers send named messages to each other using emit and on, the foundation of every real-time feature.
The Connection Lifecycle
Understand how a Socket.IO connection is established, upgraded, monitored, and torn down, including reconnection behavior and the events that mark each stage.
Custom Events and Payloads
Learn how to design well-structured custom event names and payload shapes in Socket.IO, including validation, versioning, and binary data handling for maintainable real-time APIs.
Related Reading
Related Study Notes in Programming
Browse all study notesApache Spark Study Notes
Programming · 30 topics
ProgrammingApache Flink Study Notes
Programming · 30 topics
ProgrammingHadoop Study Notes
Programming · 30 topics
ProgrammingSnowflake Study Notes
Programming · 30 topics
ProgrammingApache Airflow Study Notes
Programming · 30 topics
Programmingdbt (Data Build Tool) Study Notes
Programming · 30 topics