WebSockets and Server-Sent Events Explained

HTTP is request-response. The client asks, the server answers, conversation over. But chat apps, live dashboards, multiplayer games, and stock tickers need the server to PUSH updates to the client without being asked. WebSockets and Server-Sent Events (SSE) are the two main solutions.

The problem with plain HTTP

“Polling” — client asks every few seconds “anything new?” — wastes bandwidth and is slow. “Long polling” — client asks and server holds the connection open until something happens — works but has its own complications. WebSockets and SSE solve this properly.

WebSockets — bidirectional, persistent

WebSocket starts as an HTTP request that “upgrades” to a different protocol. After the upgrade, the connection becomes a bidirectional message channel — both sides can send anything, anytime, until one side closes it.

The handshake

Client request:
GET /chat HTTP/1.1
Host: example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

Server response:
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

[connection now uses WebSocket framing — both can send anytime]

Browser code

const ws = new WebSocket('wss://example.com/chat');

ws.onopen = () => {
  ws.send(JSON.stringify({type: 'join', room: 'general'}));
};

ws.onmessage = (event) => {
  const msg = JSON.parse(event.data);
  console.log('Received:', msg);
};

ws.onclose = () => console.log('Connection closed');
ws.onerror = (e) => console.error('Error:', e);

// Send any time
ws.send(JSON.stringify({type: 'message', text: 'Hello'}));

When to use WebSockets

  • Chat applications
  • Multiplayer games
  • Collaborative editing (Google Docs-style)
  • Live dashboards with user interaction
  • Anything bidirectional and frequent

Server-Sent Events (SSE) — one-way, simpler

SSE keeps an HTTP connection open and lets the SERVER push events to the client. The client cannot send messages back over the same channel — it would use a separate HTTP request for that.

The wire format (just plain text)

HTTP/1.1 200 OK
Content-Type: text/event-stream
Cache-Control: no-cache

event: message
data: {"text": "Hello"}

event: notification
data: {"id": 123, "kind": "alert"}

[connection stays open, more events appended]

Browser code

const es = new EventSource('/stream');

es.onmessage = (e) => {
  console.log('Default event:', e.data);
};

es.addEventListener('notification', (e) => {
  const data = JSON.parse(e.data);
  console.log('Notification:', data);
});

es.onerror = () => console.log('Connection lost (auto-reconnects)');

When to use SSE

  • Live news feeds
  • Stock tickers
  • Server-side job progress
  • Read-only live dashboards
  • Any push-only stream where bidirectional isn’t needed

WebSocket vs SSE comparison

Feature WebSocket SSE
Direction Bidirectional Server → Client only
Protocol Custom (ws://, wss://) Plain HTTP
Auto-reconnect Manual Built-in
Binary support Yes Text only
Through proxies Often blocked Works (it’s HTTP)
Browser support Universal Universal except old IE
Server complexity Higher Lower (just keep HTTP open)

Modern alternative: WebTransport

Built on HTTP/3 / QUIC. Solves WebSocket’s head-of-line blocking by using QUIC’s per-stream loss recovery. Adoption is growing but still partial. Worth knowing about for new projects.

What to learn next

That covers HTTP and the application layer. Next big section: routing — how packets find their way across networks. Up next.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *