30. WebSockets and Server-Sent Events
fetch/XHR are request-response; two APIs exist specifically for servers
pushing data without the client asking again:
// WebSocket: full-duplex, both sides can send anytime, binary or text
const ws = new WebSocket("wss://example.com/chat");
ws.onopen = () => ws.send(JSON.stringify({ type: "join", room: "general" }));
ws.onmessage = (event) => console.log("received:", event.data);
ws.onclose = (event) => console.log("closed:", event.code, event.reason);
// Server-Sent Events (SSE): one-directional, server -> client only, plain text,
// auto-reconnects on drop, and rides over ordinary HTTP (no protocol upgrade)
const sse = new EventSource("/api/live-updates");
sse.onmessage = (event) => console.log("update:", event.data);
sse.addEventListener("price-change", (event) => console.log("price:", event.data));
Choose WebSockets when the client needs to send data too (chat, multiplayer, collaborative editing); choose SSE for simpler server-push-only cases (live scores, notifications) — SSE's built-in reconnection and plain-HTTP transport make it noticeably less operational overhead when bidirectionality isn't needed.