Episode 5 of 5

Broadcasting Messages

Learn how to broadcast messages to all connected clients, to everyone except the sender, and to specific rooms using Socket.io.

Broadcasting Messages

In the previous episode, socket.emit() sent a message to one specific client. But in a chat application, when one person sends a message, everyone else needs to see it. This is where broadcasting comes in. Broadcasting sends an event to multiple clients at once.

Three Ways to Send Messages

MethodWho ReceivesCode
Emit to senderOnly the client who sent the eventsocket.emit('event', data)
Broadcast to othersAll clients except the sendersocket.broadcast.emit('event', data)
Emit to everyoneAll connected clients including the senderio.emit('event', data)

Broadcasting to All Except the Sender

io.on('connection', (socket) => {
    console.log('A user connected:', socket.id);

    socket.on('chat message', (msg) => {
        // Send the message to everyone EXCEPT the sender
        socket.broadcast.emit('chat message', msg);
    });
});

When a user sends a chat message, socket.broadcast.emit() sends it to every connected client except the one who sent it. The sender already sees their own message (we added it locally in the previous episode), so broadcasting to others avoids duplication.

Emitting to Everyone (Including Sender)

io.on('connection', (socket) => {
    socket.on('chat message', (msg) => {
        // Send the message to ALL connected clients
        io.emit('chat message', { 
            sender: socket.id, 
            message: msg 
        });
    });
});

Using io.emit() sends the event to every single connected client including the sender. This is useful when the server adds information to the message (like a timestamp or sender ID) before sending it out.

Visual Comparison

socket.emit()          → Only Client A (sender)
socket.broadcast.emit() → Clients B, C, D (everyone except A)
io.emit()              → Clients A, B, C, D (everyone)

    Client A    Client B    Client C    Client D
socket.emit:    ✅          ❌          ❌          ❌
broadcast:      ❌          ✅          ✅          ✅
io.emit:        ✅          ✅          ✅          ✅

Updating the Server for Broadcasting

Update index.js to broadcast chat messages and connection notifications:

io.on('connection', (socket) => {
    console.log('A user connected:', socket.id);

    // Notify everyone that a new user joined
    socket.broadcast.emit('user-joined', socket.id);

    // When a client sends a message, broadcast it to others
    socket.on('chat message', (msg) => {
        socket.broadcast.emit('chat message', {
            sender: socket.id,
            message: msg
        });
    });

    // Notify everyone that a user left
    socket.on('disconnect', () => {
        console.log('User disconnected:', socket.id);
        socket.broadcast.emit('user-left', socket.id);
    });
});

Updating the Client to Receive Broadcasts

Update the client script in public/index.html:

<script src="/socket.io/socket.io.js"></script>
<script>
    const socket = io();
    const messageInput = document.getElementById('message-input');
    const sendBtn = document.getElementById('send-btn');
    const chatMessages = document.getElementById('chat-messages');

    // Send message
    sendBtn.addEventListener('click', () => {
        const message = messageInput.value.trim();
        if (message) {
            socket.emit('chat message', message);
            addMessage('You: ' + message, '#e94560');
            messageInput.value = '';
        }
    });

    messageInput.addEventListener('keypress', (e) => {
        if (e.key === 'Enter') sendBtn.click();
    });

    // Receive messages from other users
    socket.on('chat message', (data) => {
        addMessage(data.sender.slice(0, 6) + ': ' + data.message, '#3498db');
    });

    // User joined notification
    socket.on('user-joined', (id) => {
        addMessage(id.slice(0, 6) + ' joined the chat', '#27ae60');
    });

    // User left notification
    socket.on('user-left', (id) => {
        addMessage(id.slice(0, 6) + ' left the chat', '#e67e22');
    });

    function addMessage(text, color) {
        const div = document.createElement('div');
        div.textContent = text;
        div.style.padding = '8px 0';
        div.style.borderBottom = '1px solid rgba(255,255,255,0.05)';
        div.style.color = color || '#eee';
        chatMessages.appendChild(div);
        chatMessages.scrollTop = chatMessages.scrollHeight;
    }
</script>

The client now listens for three events — 'chat message' from other users, 'user-joined' when someone connects, and 'user-left' when someone disconnects. Each message type is displayed in a different color for visual distinction.

Testing Broadcasting

Start the server and open http://localhost:3000 in two or more browser tabs:

node index.js
  • Tab 1: Type a message and click Send — you see "You: hello" in red
  • Tab 2: The message appears as "abc123: hello" in blue
  • Open Tab 3: Tabs 1 and 2 see "[id] joined the chat" in green
  • Close Tab 3: Tabs 1 and 2 see "[id] left the chat" in orange

When to Use Each Method

ScenarioMethod
Confirming an action to the sendersocket.emit()
Chat message seen by everyone elsesocket.broadcast.emit()
System announcement to all usersio.emit()
Private message to one userio.to(socketId).emit()
Message to a specific roomio.to('room-name').emit()

Bonus: Sending to Specific Clients

// Send to a specific socket by ID
io.to(targetSocketId).emit('private-message', {
    from: socket.id,
    message: 'Hey, this is just for you!'
});

// Send to multiple specific sockets
io.to(id1).to(id2).emit('group-msg', data);

Using io.to(socketId) you can send a message to one specific client by their socket ID. This is useful for private messages or targeted notifications.

Bonus: Rooms

// Client joins a room
socket.join('room-name');

// Send to everyone in a room (except sender)
socket.to('room-name').emit('room-message', data);

// Send to everyone in a room (including sender)
io.to('room-name').emit('room-message', data);

// Client leaves a room
socket.leave('room-name');

Rooms are channels that sockets can join and leave. They are perfect for chat rooms, game lobbies, or any feature where you need to group users. When a socket disconnects, it automatically leaves all rooms.

Key Takeaways

  • socket.emit() sends to one client — the sender
  • socket.broadcast.emit() sends to all clients except the sender
  • io.emit() sends to all connected clients including the sender
  • Use io.to(socketId).emit() for private, targeted messages
  • Rooms let you group clients and broadcast to specific groups with io.to('room').emit()
  • Broadcasting is what makes real-time features like chat, notifications, and live updates possible
  • Always choose the right emission method based on who needs to receive the message