Real-Time APIs · Real-Time Transports

WebSockets in Depth

Handshake, frames, heartbeats, close codes and message protocols.

A WebSocket starts as an HTTP request with Upgrade: websocket and becomes a persistent, full-duplex connection carrying text/binary frames. You must define your own application protocol on top (message types, IDs, acks, errors) — or use one (STOMP, graphql-ws, Socket.IO, MQTT over WS). Implement heartbeats (ping/pong) to detect dead connections through NATs and proxies, use close codes meaningfully, and authenticate during the handshake.

Common close codes

Close code Meaning
1000 Normal closure
1001 Going away (server shutdown, page navigation)
1008 Policy violation (e.g., auth failed)
1009 Message too big
1011 Internal server error
4000–4999 Application-defined
import { WebSocketServer } from "ws";

const wss = new WebSocketServer({ noServer: true, maxPayload: 64 * 1024 });
server.on("upgrade", async (req, socket, head) => {
  const user = await authenticate(req);              // cookie or token in Sec-WebSocket-Protocol / first message
  if (!user || !allowedOrigin(req.headers.origin)) return socket.destroy();
  wss.handleUpgrade(req, socket, head, (ws) => wss.emit("connection", ws, user));
});

wss.on("connection", (ws, user) => {
  let alive = true;
  ws.on("pong", () => (alive = true));
  const hb = setInterval(() => { if (!alive) return ws.terminate(); alive = false; ws.ping(); }, 30_000);
  ws.on("message", (raw) => handle(user, JSON.parse(raw.toString())));   // {type, id, payload}
  ws.on("close", () => clearInterval(hb));
});

Common pitfalls

  • No heartbeats (half-open connections linger).
  • No Origin check (cross-site WebSocket hijacking).
  • No message size limits.

Key points

  • Define an application protocol
  • Heartbeats + close codes
  • Authenticate + check Origin at handshake

Further reading: RFC 6455: The WebSocket Protocol

Practice questions

What is cross-site WebSocket hijacking?

Answer

A malicious site opens a WebSocket to your server using the victim's cookies; since WebSockets aren't covered by CORS, the server must validate the Origin header and/or use token-based auth.

Why are heartbeats needed on WebSocket connections?

Answer

Network middleboxes can silently drop idle connections; ping/pong detects dead peers so resources are freed and clients reconnect.

Open in the app to mark lessons complete, take notes and track your progress.