Complete "Managing Connection Lifecycle, Errors, and Heartbeats" first to unlock this lesson.Go to previous lesson

Introduction

In a real-time application, you rarely work with WebSockets in isolation. Clients need targeted messages (sent to one specific socket) as well as broadcast events (fired to every connected client). On top of that, most real products still expose a REST API — for example, when a user submits a form over HTTP, you want that change to appear instantly in every open WebSocket session. This lesson covers exactly that: how to send and broadcast events from a Node.js server, and how to bridge a REST endpoint with your WebSocket layer so both surfaces stay in sync.

sơ đồ kiến trúc tổng thể gồm REST client, REST endpoint, WebSocket server, và nhiều WebSocket clients với mũi tên hai chiều

Sending messages to one client vs broadcasting

Every connected socket has a unique id assigned by the server. You can use that id to send a private message:

javascript
io.to(socket.id).emit("private:message", { text: "only you see this" });

If you want every connected client to receive the same payload, you broadcast on the root namespace — no target argument needed:

javascript
io.emit("announcement", { text: "Server restarts in 5 minutes" });

There is also `socket.broadcast.emit`, which sends to everyone except the socket that triggered the event. This is useful in chat rooms where you do not want to echo the message back to the sender.

Bridging a REST endpoint with WebSocket events

The typical pattern is: REST handler does its job (write to database, validate input, etc.), then asks the WebSocket layer to push an update. Here is a minimal example using Express alongside Socket.IO:

javascript
const express = require("express");
const http = require("http");
const { Server } = require("socket.io");
const app = express();
app.use(express.json());
const server = http.createServer(app);
const io = new Server(server);
app.post("/orders", (req, res) => {
const order = { id: Date.now(), item: req.body.item, status: "created" };
io.emit("order:new", order);
res.status(201).json(order);
});
io.on("connection", (socket) => {
console.log("client connected:", socket.id);
});
server.listen(3000);

The HTTP client gets the created order in its REST response, and every browser tab connected over WebSocket receives the `order:new` event at the same time. One write, two surfaces.

sơ đồ luồng 4 bước từ REST POST đến database, broadcast event, và response về client

Targeting specific rooms

When you need finer control than "everyone" or "one socket", use rooms. A room is just a named channel that sockets join or leave:

javascript
io.on("connection", (socket) => {
socket.join("orders");
socket.to("orders").emit("order:new", order);
});

`socket.to("orders")` reaches every socket in that room except the sender. `io.to("orders").emit(...)` reaches everyone in the room including the sender. Rooms are the standard way to implement per-user, per-team, or per-topic feeds without writing custom routing logic.

Common mistakes

Calling `io.emit` inside the REST handler is fine, but do not forget that the REST response and the WebSocket emit are independent — if the WebSocket layer crashes, the HTTP request still returns success. For critical flows, wrap the broadcast in a try/catch and log failures. Another frequent error is mixing `socket.emit` (sends to the current socket only) with `io.emit` (sends globally) and assuming they behave the same. Pick the one that matches your intent. Finally, never trust the `socket.id` sent from the client — always look it up server-side from your authenticated session before sending private data.

Summary

You now have three delivery modes: `socket.emit` for the current client, `io.emit` for global broadcast, and rooms for targeted groups. Pairing a REST handler with `io.emit` (or `io.to(room).emit`) is the standard bridge pattern that keeps HTTP and WebSocket surfaces consistent. Keep the broadcast inside the REST handler after the main business logic, handle WebSocket failures gracefully, and always verify identities server-side before sending private payloads.

Lesson practice

Lesson Checkpoint

Review what you learned and get feedback on your work.

0/1
Answered · 0/1
Broadcasting Events and Integrating with a REST API