Two-Way, Persistent Connections
WebSockets
WebSockets keep a connection open for bidirectional messages. Use the `ws` package on the Node side.
What you'll learn
- Start a WebSocket server with `ws`
- Send and receive messages
- Know when to choose WS vs SSE
A WebSocket is a single TCP connection that stays open and lets both sides send messages at any time. Real-time chat, live dashboards, multiplayer.
The Most Common Library — ws
npm install ws import { WebSocketServer } from "ws";
const wss = new WebSocketServer({ port: 3001 });
wss.on("connection", (ws) => {
console.log("client connected");
ws.on("message", (raw) => {
const msg = JSON.parse(raw.toString());
console.log("got", msg);
ws.send(JSON.stringify({ echo: msg }));
});
ws.on("close", () => console.log("client gone"));
}); On the browser:
const ws = new WebSocket("ws://localhost:3001");
ws.onopen = () => ws.send(JSON.stringify({ hello: "server" }));
ws.onmessage = (e) => console.log("got", JSON.parse(e.data)); Broadcasting
Send a message to every connected client:
wss.on("connection", (ws) => {
ws.on("message", (raw) => {
for (const client of wss.clients) {
if (client.readyState === WebSocket.OPEN) {
client.send(raw.toString());
}
}
});
}); The skeleton of a chat server.
Sharing the HTTP Port
Run WS on the same port as your HTTP server using “upgrade”:
import { createServer } from "node:http";
import { WebSocketServer } from "ws";
const httpServer = createServer((req, res) => res.end("http"));
const wss = new WebSocketServer({ noServer: true });
httpServer.on("upgrade", (req, socket, head) => {
if (req.url === "/ws") {
wss.handleUpgrade(req, socket, head, (ws) => {
wss.emit("connection", ws, req);
});
} else {
socket.destroy();
}
});
httpServer.listen(3000); Now port 3000 serves HTTP + WebSocket on /ws. Same TCP socket.
WS vs SSE
| Use Case | Pick |
|---|---|
| Server → client push only (live feed, AI tokens) | SSE — simpler, auto-reconnect, works over HTTP/2 |
| Two-way (chat, multiplayer, collab) | WebSocket |
| Browsers with strict proxies | SSE (looks like normal HTTP) |
Pick the simpler tool. WS is more powerful but adds complexity.
End of Chapter
That wraps low-level HTTP. Next chapter: Express — most of what you’ll actually ship.
Express →