HTTP Connections &
Real-Time Communication

When the Server Needs to Talk Back

"HTTP was designed for fetching documents, not for interactive applications. Every technique in this deck is a workaround for this single constraint."

CSE 135 — Full Overview | Review Questions

Section 1The Request-Response Constraint

The client asks, the server answers — and that's it.

The Core Problem

Client Server │ │ │──── GET /messages ───────────────────────>│ │<──── 200 OK (3 messages) ────────────────│ │ │ │ ... 10 seconds pass ... │ │ │ ← New message arrives │ │ from another user! │ │ │ Client has no idea. │ ← Server has no way │ Still showing 3 messages. │ to deliver it. │ │ │ Only when client asks again: │ │──── GET /messages ───────────────────────>│ │<──── 200 OK (4 messages) ────────────────│

HTTP is like postal mail: you send a letter (request), wait for a reply (response), and the post office has no way to deliver a letter you didn't ask for. A telephone is bidirectional — HTTP is not.

HTTP was designed for fetching documents, not interactive applications. The server literally cannot send data to the client unless the client asks first. Every technique on this page is a workaround for this single constraint.

Section 2When You Need More Than Request-Response

Eight scenarios where the server knows something the client doesn't.

Scenarios Where Request-Response Fails

ScenarioWhy Request-Response FailsWhat's Needed
Chat / messagingMessages arrive from other users; your client doesn't knowInstant delivery
Live scoresScores change continuously; client shows stale dataContinuous updates
NotificationsServer-side events happen unpredictablyPush when event occurs
Collaborative editingMultiple users change the same documentBidirectional real-time sync
Progress indicatorsServer-side task running; client wants updatesServer pushes progress
Multiplayer gamesOther players' actions must appear immediatelyLow-latency bidirectional
IoT / dashboardsSensor data streams in continuouslyContinuous data feed
Financial tradingSub-second price changes; stale data costs moneyLowest latency updates
If your data changes less often than every 30 seconds and users can tolerate stale data, plain request-response may be all you need. A weather dashboard that updates every 5 minutes doesn't need WebSockets.

Section 3Polling

The simplest workaround: ask repeatedly on a timer.

How Polling Works

Client Server │ │ │──── GET /updates ────────────────────────>│ │<──── 200 OK (no change) ─────────────────│ │ │ │ ... wait 5 seconds ... │ │ │ │──── GET /updates ────────────────────────>│ │<──── 200 OK (no change) ─────────────────│ │ │ │ ... wait 5 seconds ... │ ← New data arrives! │ │ │──── GET /updates ────────────────────────>│ │<──── 200 OK (new data!) ─────────────────│ │ │ │ Latency: 0 to 5 seconds (avg 2.5s) │

Tradeoffs

  • Latency: 0 to N seconds (average N/2). Poll every 5s → 2.5s average delay.
  • Wasted requests: Most responses return "no change."
  • Server load scales linearly: More users = more requests, regardless of changes.
  • Simple to implement: Works everywhere. Just setInterval + fetch.
Polling math: 10,000 users × 5s interval = 2,000 requests/second of pure overhead, most returning "no change." This is why polling doesn't scale for real-time features with large user bases.

Section 4Long Polling

Server holds the connection open until it has something to say.

How Long Polling Works

Client Server │ │ │──── GET /updates (long poll) ────────────>│ │ │ Server holds connection │ ... waiting ... │ open. No response yet. │ │ │ │ ← Event occurs! │<──── 200 OK (new data!) ─────────────────│ Server responds immediately │ │ │──── GET /updates (re-poll) ──────────────>│ Client re-requests instantly │ │ Server holds again... │ ... waiting ... │ │ │ │ timeout! ─│ │<──── 200 OK (no change, timeout) ────────│ After 30-60s, respond anyway │ │ │──── GET /updates (re-poll) ──────────────>│ Client re-requests

Limitations

  • Each client holds a server connection open. 10,000 users = 10,000 open connections.
  • Proxy timeouts: Many proxies terminate after 60–120 seconds.
  • Thundering herd: Popular event → all clients respond + re-request simultaneously.
Long polling was the dominant real-time technique from ~2005–2012. It powered Facebook's original chat, the Comet pattern, and early AJAX chat apps. Many systems still use it as a fallback.

Section 5Server-Sent Events (SSE)

HTTP's built-in push mechanism — a response that never ends.

SSE Protocol & EventSource API

Client Server │ │ │──── GET /events ─────────────────────────>│ │ Accept: text/event-stream │ │ │ │<──── 200 OK ─────────────────────────────│ │ Content-Type: text/event-stream │ │ Connection kept open │ │ │ │<──── data: {"user":"alice","msg":"hi"} │ Event 1 │ │ │<──── data: {"user":"bob","msg":"hello"} │ Event 2 │ │ │ ... minutes pass ... │ │ │ │<──── data: {"user":"alice","msg":"bye"} │ Event 3 │ │ │ Connection stays open indefinitely │ │ Server writes whenever it has data │

SSE is unidirectional (server → client). The client uses regular fetch to send data back. The browser's EventSource API handles reconnection automatically, including resuming from the last event ID.

SSE is just HTTP with a response that never ends. No upgrade, no new protocol. The EventSource API handles reconnection automatically. For server-to-client push, SSE is often all you need.

SSE Message Format & Limits

FieldPurposeExample
data:Event payload (can span multiple lines)data: {"score": 42}
event:Named event type (triggers specific listeners)event: notification
id:Event ID for reconnection (browser sends Last-Event-ID)id: 1001
retry:Reconnection interval in millisecondsretry: 5000

Built-in reconnection: If the connection drops, the browser automatically reconnects and sends Last-Event-ID. The server resumes from where it left off — no client-side reconnection logic needed.

The 6-connection-per-domain limit on HTTP/1.1 is a real problem. If a user opens your site in 6 tabs with SSE, all connections are consumed. Use HTTP/2 (multiplexes streams) or a dedicated subdomain.

Section 6WebSockets

Full-duplex bidirectional communication — the only browser API where both sides talk freely.

The WebSocket Handshake

Client Server │ │ │──── HTTP Request ────────────────────────>│ │ GET /chat HTTP/1.1 │ │ Upgrade: websocket │ │ Connection: Upgrade │ │ Sec-WebSocket-Key: dGhlIHNh... │ │ │ │<──── HTTP Response ──────────────────────│ │ HTTP/1.1 101 Switching Protocols │ │ Upgrade: websocket │ │ Sec-WebSocket-Accept: s3pPL... │ │ │ │ ══════════════════════════════════════ │ │ WebSocket connection established │ │ Full-duplex, bidirectional │ │ ══════════════════════════════════════ │ │ │ │──── "Hello from client" ─────────────────>│ │<──── "Hello from server" ────────────────│ │<──── "New message from Bob" ─────────────│ │──── "Thanks, got it" ───────────────────>│ │ │ │ Either side can send at any time │

Frame Types

  • Text frames: UTF-8 data (usually JSON)
  • Binary frames: Raw binary (images, audio, protobufs)
  • Ping/Pong: Keepalive — keeps connection alive through NATs/firewalls
  • Close: Graceful shutdown — either side can initiate

When WebSockets Shine & When They Don't

Use WebSockets For

  • Chat applications — both sides send messages unpredictably
  • Multiplayer games — player actions in real-time, both directions
  • Collaborative editing — Google Docs-style simultaneous changes
  • Live trading platforms — sub-second bidirectional updates
WebSockets are the only browser API for true bidirectional communication. If your app needs client AND server to send messages at any time, WebSockets are the right tool. For server-to-client only, SSE is simpler.
WebSocket connections are stateful. Server crash = all clients disconnected. Needs sticky sessions or Redis pub/sub for horizontal scaling. This is why they're harder to deploy than stateless HTTP.

Section 7Choosing the Right Approach

Start simple. Upgrade when you hit limits, not before.

Comparison Table

AspectPollingLong PollingSSEWebSockets
DirectionClient → ServerClient → ServerServer → ClientBidirectional
ProtocolHTTPHTTPHTTPWS (after upgrade)
ConnectionNew each timeHeld, re-establishedSingle persistent HTTPSingle persistent WS
Latency0 to N sec (avg N/2)Near-instantNear-instantNear-instant
Server loadHigh (constant)Moderate (held)Low (1 per client)Low (1 per client)
BandwidthHigh (HTTP overhead)ModerateLowVery low
Client complexityVery lowLowVery low (EventSource)Moderate
Server complexityVery lowModerateModerateHigh
Auto-reconnectN/AManualBuilt-inManual
Proxy/firewallWorks everywhereWorks everywhereUsually worksMay be blocked
ScalabilityPoor at high freqModerateGoodGood (but stateful)
Best forLow-freq checksModerate real-timePush: feeds, progressChat, games, collab

Decision Tree

Need bidirectional communication? (Both client AND server send frequently) │ ├── YES ──→ WebSockets │ (chat, games, collaboration) │ NO │ Server needs to push data to client? │ ├── YES ──→ Server-Sent Events (SSE) │ (notifications, live feeds, progress) │ NO │ Data changes frequently (every <30 seconds)? │ ├── YES ──→ Long Polling │ (near-real-time without special protocol) │ NO ──→ Regular Polling (dashboard refresh, status checks)
The best technique is the simplest one that meets your requirements. Polling is not shameful — it's battle-tested and works everywhere. SSE handles most server-push scenarios. Reserve WebSockets for true bidirectional needs.

Section 8Implementation Realities

Production is messier than tutorials — proxies, firewalls, and mobile networks.

Proxies & Firewalls

TechniqueCorporate ProxyCDNMobile CarrierLoad Balancer
PollingWorksWorks (cacheable)WorksWorks
Long PollingWorks (may timeout)Works (not cacheable)Works (may timeout)Works
SSEMay buffer/breakMay bufferMay bufferNeeds config
WebSocketsMay block upgradeRequires WS supportUsually worksNeeds sticky sessions

Corporate proxies are especially problematic: SSL inspection (MITM), buffered streaming responses, blocked Upgrade headers. HTTPS mitigates many of these issues.

Mobile Challenges & Fallbacks

Mobile Network Problems

ChallengeMechanismSolution
NAT timeoutCarriers kill idle TCP after 30–60sHeartbeat pings every 15–30s
Network switchingWiFi → cellular drops all TCPAuto-reconnect with exponential backoff
Battery drainPersistent connections prevent radio sleepReduce ping frequency; batch updates

Fallback Strategy

Socket.IO tries WebSocket first, detects failure, and falls back to long polling — transparently. The application code doesn't change.

Corporate networks are where your real-time features go to die. Always test behind a proxy and have a polling fallback ready.

Section 9Beyond WebSockets

Newer technologies addressing WebSocket limitations.

What Comes Next

  • WebTransport: Built on HTTP/3 (QUIC). Multiple independent streams — a dropped packet on one stream doesn't block others (unlike TCP-based WebSockets). Promising for gaming and latency-sensitive apps.
  • HTTP/2 & HTTP/3: HTTP/2 multiplexes many streams over one TCP connection, eliminating the 6-connection limit that plagues SSE. HTTP/3 (QUIC/UDP) adds 0-RTT setup and removes TCP head-of-line blocking.
  • GraphQL Subscriptions: A query language feature over WebSockets (or SSE). Write subscription { newMessage { text, author } } and the server pushes matching data.
  • gRPC Streaming: Google's RPC framework supports server, client, and bidirectional streaming over HTTP/2. Common in microservice backends.
All of these are abstractions over the same core idea: a long-lived connection where the server can send data without being asked. The protocol details differ, but the motivation is identical.

SummaryKey Takeaways

10 concepts of real-time web communication in one table.

Connections & Real-Time at a Glance

ConceptKey Takeaway
The ProblemHTTP is request-response only. The server cannot contact the client — every real-time technique is a workaround.
When You Need MoreChat, live scores, notifications, collaboration, games, trading — the server knows something the client doesn't.
PollingClient asks repeatedly on a timer. Simple and universal, but wastes bandwidth. Fine for low-frequency updates.
Long PollingServer holds connection until it has data. Near-instant delivery, still just HTTP, but holds connections open.
SSEStandardized HTTP streaming. EventSource API with built-in reconnection. Unidirectional (server → client).
WebSocketsFull-duplex bidirectional. Starts as HTTP, upgrades to WS. Stateful and harder to scale.
ChoosingStart simple. Polling for infrequent. SSE for push. WebSockets only for true bidirectional needs.
InfrastructureProxies buffer SSE, firewalls block WS upgrades. Polling works everywhere. Always have a fallback.
The FutureWebTransport, HTTP/3, GraphQL Subscriptions, gRPC Streaming — same core idea, different protocols.