WebSockets, SSE and long polling
WebSockets, SSE and Long Polling
Learn how web applications deliver live updates through full-duplex WebSocket connections, one-way Server-Sent Event streams and repeated long-polling requests.
Introduction
Traditional HTTP communication is request-driven. A client sends a request, and a server returns a response. This model works well when the client knows when information is required.
Some applications need the server to deliver updates shortly after events occur, without waiting for a user to refresh the page.
Examples include:
- Chat messages
- Notifications
- Live dashboards
- Job-progress updates
- Delivery tracking
- Collaborative editing
- Monitoring events
- Live scores
- Market-data updates
- Online multiplayer interactions
Three common browser communication techniques are:
- WebSockets for persistent bidirectional communication
- Server-Sent Events for persistent server-to-client event streaming
- Long polling for server-delayed responses followed by repeated requests
Core idea: Choose a real-time communication technique from the required direction of communication, update frequency, reliability model, infrastructure support, reconnection behaviour, message size and expected number of concurrent clients.
In the System Design curriculum, WebSockets, SSE and Long Polling is Topic 3.7 and completes the Networking and Web Request Lifecycle module. The accompanying practical work includes building a WebSocket echo service.
Prerequisites
| # | Prerequisite | Why It Is Needed |
|---|---|---|
| 1 | TCP/IP and UDP | Real-time techniques depend on underlying transport behaviour. |
| 2 | DNS and routing | The client must locate and reach the communication endpoint. |
| 3 | TLS | Production connections require appropriate confidentiality, integrity and authentication. |
| 4 | HTTP/1.1, HTTP/2 and HTTP/3 | SSE and long polling use HTTP, while WebSocket establishment is related to HTTP communication. |
| 5 | Cookies and sessions | Persistent connections often need authenticated session context. |
| 6 | JavaScript event handling | Browser clients process asynchronous connection and message events. |
The Real-time Communication Problem
A server receives new information.
Question:
How does the browser learn about the update
without requiring the user to refresh the page?
Traditional Polling
Client -> Is new data available?
Server -> No
Wait for polling interval.
Client -> Is new data available?
Server -> No
Wait for polling interval.
Client -> Is new data available?
Server -> Yes, here is the update.
Traditional polling sends requests at fixed intervals. It is simple but can create many responses containing no new data, while update latency depends on the polling interval.
Communication Models
| Technique | Communication Direction | Connection Model |
|---|---|---|
| WebSocket | Bidirectional | Persistent framed connection |
| Server-Sent Events | Server to client | Long-lived HTTP response stream |
| Long polling | Primarily server to client through repeated client requests | One delayed HTTP response per polling cycle |
| Traditional polling | Client requests updates | Repeated HTTP requests at fixed intervals |
WebSockets
The WebSocket protocol provides two-way communication between a client and server. After connection establishment, both endpoints can send framed messages independently.
Client Server
| |
| Opening handshake |
|---------------------------------------->|
| |
| Handshake accepted |
|<----------------------------------------|
| |
| Client message |
|---------------------------------------->|
| |
| Server message |
|<----------------------------------------|
| |
| Messages can flow in either direction |
|<=======================================>|
WebSockets are appropriate when:
- Both client and server frequently send messages
- Low message-delivery latency is important
- A persistent interactive channel is required
- Text and binary messages are needed
- Repeated HTTP request overhead should be avoided
WebSocket Opening Handshake
A WebSocket connection begins with an opening handshake. In the traditional HTTP/1.1 form, the client requests a protocol upgrade.
Client Request
GET /realtime HTTP/1.1
Host: app.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: random-base64-value
Sec-WebSocket-Version: 13
Origin: https://app.example.com
Server Response
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: calculated-response-value
After a successful handshake, communication follows WebSocket message framing rather than ordinary HTTP request-response semantics on that connection.
Origin validation: Browser cookies can accompany a WebSocket handshake when cookie rules permit. A server should validate the expected Origin and authentication context rather than assuming that a successful network connection is authorized.
ws and wss
| Scheme | Meaning |
|---|---|
ws:// |
WebSocket communication without TLS protection |
wss:// |
WebSocket communication protected through TLS |
Production browser applications should normally use
wss:// so connection authentication, confidentiality and
integrity are appropriately protected.
WebSocket Frames and Messages
WebSocket data is transferred through frames. An application message can occupy one frame or be fragmented across several frames.
Application Message
|
+--> Frame 1: beginning
+--> Frame 2: continuation
+--> Frame 3: final fragment
WebSocket frame categories include:
- Text data frames
- Binary data frames
- Continuation frames
- Ping control frames
- Pong control frames
- Close control frames
Browser WebSocket Client
const socket =
new WebSocket(
"wss://app.example.com/realtime"
);
socket.addEventListener(
"open",
() => {
const message = {
type: "subscribe",
channel: "job-status"
};
socket.send(
JSON.stringify(message)
);
}
);
socket.addEventListener(
"message",
(event) => {
const message =
JSON.parse(event.data);
console.log(
"Received:",
message
);
}
);
socket.addEventListener(
"error",
() => {
console.error(
"WebSocket error."
);
}
);
socket.addEventListener(
"close",
(event) => {
console.log(
"Connection closed:",
event.code,
event.reason
);
}
);
Production code should validate every received message before using its fields.
WebSocket Application Protocol
WebSocket supplies message transport but does not define the meaning of application messages.
{
"type": "chat.message",
"messageId": "msg-1042",
"conversationId": "room-27",
"payload": {
"text": "Example message"
}
}
An application protocol should define:
- Message types
- Required and optional fields
- Message identifiers
- Request-response correlation
- Versioning
- Error messages
- Authorization rules
- Size limits
- Delivery and ordering behaviour
Ping, Pong and Heartbeats
A persistent connection can appear open even when an intermediary or remote endpoint is no longer usable. Heartbeat mechanisms help detect stalled or abandoned connections.
Server sends ping
|
v
Client responds with pong
|
+--> Response received:
| connection remains active
|
+--> Response missing by deadline:
close connection
release resources
Browser WebSocket APIs do not expose protocol-level ping and pong frames directly to ordinary JavaScript. Applications can implement an application-level heartbeat where necessary.
Application Heartbeat
const heartbeatInterval =
30000;
const timer =
setInterval(
() => {
if (
socket.readyState ===
WebSocket.OPEN
) {
socket.send(
JSON.stringify({
type: "heartbeat",
sentAt:
new Date().toISOString()
})
);
}
},
heartbeatInterval
);
socket.addEventListener(
"close",
() => {
clearInterval(timer);
}
);
The interval and timeout should be selected from infrastructure idle timeouts, expected network conditions and resource requirements.
WebSocket Reconnection
The browser WebSocket API does not automatically restore application state after a disconnected connection. The application should use a bounded reconnection policy.
let reconnectAttempt = 0;
let activeSocket = null;
function calculateDelay(
attempt
) {
const maximumDelay = 30000;
const baseDelay = 1000;
const exponentialDelay =
Math.min(
maximumDelay,
baseDelay * (2 ** attempt)
);
const randomJitter =
Math.floor(
Math.random() * 500
);
return exponentialDelay +
randomJitter;
}
function connect() {
activeSocket =
new WebSocket(
"wss://app.example.com/realtime"
);
activeSocket.addEventListener(
"open",
() => {
reconnectAttempt = 0;
}
);
activeSocket.addEventListener(
"message",
handleMessage
);
activeSocket.addEventListener(
"close",
() => {
const delay =
calculateDelay(
reconnectAttempt
);
reconnectAttempt += 1;
setTimeout(
connect,
delay
);
}
);
}
Reconnection should restore subscriptions and recover missed events according to the application's delivery model.
Server-Sent Events
Server-Sent Events, commonly abbreviated as SSE, allow a server to stream text events to a browser over a long-lived HTTP response.
Browser
|
| GET /events
v
Server
|
| HTTP response remains open
|
+--> Event 1
+--> Event 2
+--> Event 3
+--> Event 4
SSE is suitable when:
- Updates primarily flow from server to client
- Text event data is sufficient
- Automatic browser reconnection is useful
- Normal HTTP authentication and infrastructure are preferred
- The client can send occasional commands through separate HTTP requests
SSE Response
An SSE endpoint returns content using the
text/event-stream media type.
HTTP/1.1 200 OK
Content-Type: text/event-stream
Cache-Control: no-cache
Connection: keep-alive
id: 101
event: job-progress
data: {"jobId":"42","progress":25}
id: 102
event: job-progress
data: {"jobId":"42","progress":50}
Events are separated by a blank line. SSE event streams are interpreted as UTF-8 text.
SSE Fields
| Field | Purpose |
|---|---|
data |
Contains the event data |
event |
Defines a custom event type |
id |
Updates the client's last event identifier |
retry |
Suggests a reconnection delay in milliseconds |
| Comment line | A line beginning with a colon can be used for comments or connection activity |
Browser SSE Client
const events =
new EventSource(
"/events"
);
events.addEventListener(
"open",
() => {
console.log(
"Event stream opened."
);
}
);
events.addEventListener(
"job-progress",
(event) => {
const update =
JSON.parse(event.data);
console.log(
update.jobId,
update.progress
);
}
);
events.addEventListener(
"message",
(event) => {
console.log(
"Default event:",
event.data
);
}
);
events.addEventListener(
"error",
() => {
console.error(
"Event stream interrupted."
);
}
);
Close the Stream
events.close();
PHP SSE Endpoint
<?php
declare(strict_types=1);
session_start();
if (!isset(
$_SESSION['user_id']
)) {
http_response_code(401);
exit;
}
header(
'Content-Type: text/event-stream'
);
header(
'Cache-Control: no-cache'
);
header(
'X-Accel-Buffering: no'
);
$eventId =
(string)time();
$payload = [
'type' => 'job-progress',
'jobId' => '42',
'progress' => 50
];
echo 'id: ' .
$eventId .
"\n";
echo "event: job-progress\n";
echo 'data: ' .
json_encode(
$payload,
JSON_THROW_ON_ERROR
) .
"\n\n";
if (
ob_get_level() > 0
) {
ob_flush();
}
flush();
This example emits one event and then completes. A long-lived production stream requires controlled waiting, disconnect detection, heartbeats, deadlines, bounded event delivery and graceful shutdown.
SSE Reconnection
The browser's EventSource implementation reconnects when the connection is interrupted, unless the stream is deliberately closed or the server returns a response that stops reconnection according to the SSE rules.
Connection opens
|
v
Server sends events
|
v
Connection is interrupted
|
v
Browser waits
|
v
Browser reconnects
|
v
Event delivery continues
Automatic reconnection restores the transport connection, but the application must define how missed events are recovered.
Last-Event-ID
An SSE server can assign an identifier to each event.
id: 501
event: notification
data: {"message":"Build started"}
id: 502
event: notification
data: {"message":"Build completed"}
After a disconnection, the client can provide the last event identifier during reconnection. The server can use it to resume after the last acknowledged event when the application retains replayable event history.
Client last received:
Event 501
Connection interrupted.
Client reconnects with:
Last-Event-ID: 501
Server resumes with:
Event 502
Delivery rule: Event identifiers do not automatically create reliable delivery. The server needs an ordered event log, retention policy and replay logic when missed-event recovery is required.
SSE Heartbeat Comments
Periodic comment lines can keep the stream active through intermediaries and help detect connection failure.
: heartbeat
id: 601
event: status
data: {"status":"running"}
: heartbeat
Heartbeat frequency should account for proxy, load-balancer and server idle timeout policies.
Long Polling
In long polling, the client sends an HTTP request and the server delays the response until an event becomes available or a timeout is reached.
Client sends request
|
v
Server checks for new events
|
+--> Event available:
| respond immediately
|
+--> No event:
hold request open
|
+--> Event becomes available:
| return event
|
+--> Timeout:
return empty result
Client immediately sends next request.
Long-polling Browser Client
let stopped = false;
let cursor = null;
async function longPoll() {
while (!stopped) {
const parameters =
new URLSearchParams();
if (cursor !== null) {
parameters.set(
"after",
cursor
);
}
try {
const response =
await fetch(
`/events/poll?${parameters}`,
{
method: "GET",
credentials: "same-origin",
headers: {
Accept:
"application/json"
}
}
);
if (!response.ok) {
throw new Error(
`HTTP ${response.status}`
);
}
const result =
await response.json();
for (
const event of
result.events
) {
handleEvent(event);
cursor = event.id;
}
} catch (error) {
console.error(
"Polling failed:",
error
);
await new Promise(
(resolve) => {
setTimeout(
resolve,
2000
);
}
);
}
}
}
function stopLongPolling() {
stopped = true;
}
longPoll();
The cursor allows the client to request events after the last successfully processed item.
Conceptual PHP Long-polling Endpoint
<?php
declare(strict_types=1);
session_start();
if (!isset(
$_SESSION['user_id']
)) {
http_response_code(401);
exit;
}
header(
'Content-Type: application/json'
);
$after =
$_GET['after'] ?? null;
$deadline =
microtime(true) + 25.0;
$events = [];
do {
/*
* Replace with a bounded event-store query.
*/
$events =
findEventsAfter(
userId:
(int)$_SESSION['user_id'],
cursor:
is_string($after)
? $after
: null
);
if ($events !== []) {
break;
}
usleep(
250000
);
} while (
microtime(true) < $deadline
);
echo json_encode(
[
'events' => $events
],
JSON_THROW_ON_ERROR
);
Repeated database queries inside each waiting request can create heavy load. Production implementations should use appropriate event notification, queueing or asynchronous waiting mechanisms rather than unrestricted repeated queries.
WebSockets vs SSE vs Long Polling
| Area | WebSocket | SSE | Long Polling |
|---|---|---|---|
| Direction | Bidirectional | Server to client | Client requests, server returns available events |
| Data model | Text, binary and control frames | UTF-8 text events | Normal HTTP response content |
| Connection | Persistent WebSocket connection | Persistent HTTP response | Repeated delayed HTTP requests |
| Browser reconnection | Application-managed | Built into EventSource | Application-managed |
| Missed-event recovery | Application-defined | Can use event IDs and replay | Can use cursors and replay |
| Per-update HTTP overhead | No ordinary HTTP request per message after establishment | No new HTTP request per event while stream remains open | New HTTP request-response cycle after each completion |
| Typical use | Interactive two-way applications | Notifications, feeds and progress streams | Compatibility-oriented updates and simpler legacy integration |
Choosing the Right Technique
| Requirement | Likely Choice |
|---|---|
| Frequent bidirectional messages | WebSocket |
| Server sends a continuous text event stream | SSE |
| Client sends commands through normal HTTP while receiving updates | SSE plus ordinary HTTP requests |
| Existing infrastructure supports only ordinary request-response HTTP reliably | Long polling |
| Binary real-time messages are required | WebSocket |
| Automatic browser reconnection and event IDs are useful | SSE |
| Updates are infrequent and modest delay is acceptable | Long polling or periodic polling can be considered |
Design strategy: Prefer the simplest technique that satisfies the communication requirement. Do not introduce a bidirectional stateful protocol when the application needs only a one-way notification stream.
Event Delivery Semantics
None of these communication mechanisms automatically guarantees exactly-once business processing.
| Delivery Model | Application Behaviour |
|---|---|
| At most once | An event is not retried after uncertain delivery, so it can be missed |
| At least once | An event can be retried, so the consumer must handle duplicates |
| Effectively once | Retries are permitted, while identifiers and idempotent processing prevent duplicate business effects |
Reliable event processing can require:
- Unique event identifiers
- Ordered sequence numbers
- Durable event storage
- Client acknowledgement
- Replay from a cursor
- Duplicate detection
- Idempotent event handling
Backpressure
Backpressure is required when the event producer can generate data faster than a client can receive or process it.
Fast Producer
|
v
Bounded Event Queue
|
+--> Client keeps up:
| continue delivery
|
+--> Client falls behind:
coalesce events
drop permitted events
disconnect client
or apply another defined policy
A backpressure policy should define:
- Maximum queued messages per connection
- Maximum queued bytes
- Events that can be combined
- Events that can be discarded
- Client-disconnection threshold
- Replay behaviour after reconnection
Horizontal Scaling
Clients
|
v
Load Balancer
|
+--> Realtime Server A --+
| |
+--> Realtime Server B --+--> Shared Event Broker
| |
+--> Realtime Server C --+
|
v
Application Events
In a scaled architecture, an event can be generated on one application instance while the target client is connected to another instance.
A scalable design can require:
- A shared event broker
- Subscription management
- Connection ownership tracking
- Per-user or per-channel routing
- Event replay storage
- Graceful connection draining
- Connection-count and queue metrics
Sticky Connections
A long-lived connection remains attached to the server instance that accepted it. Load balancer affinity can influence which instance receives later connections, but a shared event-distribution mechanism is often still needed.
Affinity alone does not solve:
- Instance failure
- Deployment draining
- Missed-event recovery
- Uneven connection distribution
- Events generated by another instance
Graceful Shutdown
Deployment or shutdown begins
|
v
Stop accepting new connections
|
v
Mark instance as draining
|
v
Notify or close existing clients
|
v
Allow reconnection to healthy instances
|
v
Release subscriptions and buffers
|
v
Terminate instance
A shutdown policy should define connection-drain duration, close reasons, reconnection behaviour and treatment of queued messages.
Authentication
Authentication should be completed when the connection is established and re-evaluated when the security context changes.
Authentication options can include:
- Secure session cookies
- Short-lived access credentials
- Mutual TLS for selected service clients
- A one-time connection credential
wss://app.example.com/realtime?token=long-lived-secret
Use an approved protected authentication channel.
Avoid exposing reusable credentials through:
- URLs
- Browser history
- Proxy logs
- Analytics
- Referrer information
- Diagnostic screenshots
Authorization
A connected client must be authorized for every subscription, channel, command and protected event.
Authenticated connection
|
v
Client requests subscription to channel A
|
v
Server evaluates authorization
|
+--> Allowed:
| subscribe
|
+--> Denied:
reject request
Do not authorize a subscription only from a client-supplied room, account, user or tenant identifier.
Security Considerations
Real-time endpoints should protect against:
- Unauthorized connections
- Unauthorized channel subscriptions
- Cross-site WebSocket hijacking
- Oversized messages
- Malformed payloads
- Connection floods
- Event-subscription abuse
- Slow consumers
- Unbounded outbound queues
- Replay of sensitive commands
- Information leakage between users or tenants
Recommended Controls
- Use TLS-protected communication.
- Validate WebSocket Origin values.
- Authenticate every connection.
- Authorize every channel and command.
- Limit connections per account and source.
- Apply message and event-size limits.
- Validate message schemas.
- Use bounded queues.
- Apply idle and maximum-lifetime policies.
- Redact credentials and event payloads from logs.
Important Metrics
| Metric | What It Helps Explain |
|---|---|
| Active connections | Current persistent-connection demand |
| Connection establishment rate | New and reconnecting clients |
| Connection duration | Normal lifecycle and premature disconnections |
| Messages or events per second | Real-time workload volume |
| Delivery latency | Time from event creation to client receipt |
| Reconnect rate | Network, deployment or idle-timeout instability |
| Outbound queue depth | Slow clients and backpressure |
| Dropped or coalesced events | Overload-policy activity |
| Authentication failures | Invalid or expired connection credentials |
| Authorization rejections | Denied subscription or command attempts |
| Long-poll timeout rate | Requests completed without new events |
| Missed-event replay count | Recovery activity after reconnecting |
Test a WebSocket Endpoint
A WebSocket-capable command-line client can connect to an approved endpoint. Exact commands depend on the installed client.
websocat wss://app.example.com/realtime
Do not place production credentials directly in shell history. Tool availability and options vary by environment.
Test an SSE Endpoint
curl -N \
-H 'Accept: text/event-stream' \
https://app.example.com/events
The -N option disables curl's output buffering so streamed
events can be displayed as they arrive.
Test a Long-polling Endpoint
curl -v \
'https://app.example.com/events/poll?after=500'
Observe response time, returned cursor, event identifiers and timeout behaviour.
Inspect Connections
ss -tnp
ss -tn state established
Persistent WebSocket and HTTP streaming connections can appear as established transport connections. Identifying the application protocol can require process, TLS and application evidence.
Packet Capture
sudo tcpdump -i any -nn host SERVER_ADDRESS and port 443
TLS normally prevents direct payload inspection without separately approved diagnostic key material. Packet captures can still show connection establishment, timing, packet loss and closure.
Diagnostic warning: Real-time traffic can contain private messages, tokens and user activity. Protect packet captures, event logs and test credentials according to the applicable data-handling policy.
Troubleshooting Workflow
- Confirm the endpoint URL and expected communication technique.
- Resolve the hostname and verify the selected route.
- Test transport and TLS connectivity.
- Check authentication and Origin validation.
- Confirm proxy and load-balancer support for long-lived connections.
- Inspect idle-timeout configuration.
- Verify message or event framing.
- Inspect reconnection and replay behaviour.
- Check connection counts and outbound queues.
- Verify channel-level authorization.
- Inspect application and broker health.
- Test graceful shutdown and reconnection.
Common Mistakes
Using WebSockets for One-way Infrequent Updates
SSE or long polling can provide a simpler design when the client does not require frequent bidirectional messages.
Assuming WebSocket Provides an Application Protocol
The application must define message types, schemas, errors, identifiers, authorization and versioning.
Ignoring Origin Validation
Browser authentication cookies can accompany a handshake. Validate the expected Origin and authentication context.
Keeping Unbounded Outbound Queues
A slow client can cause continuous memory growth unless queue size and backpressure are controlled.
Reconnecting Every Client Immediately
Immediate retries after an outage can create a reconnection storm. Use exponential backoff with jitter.
Assuming SSE Reconnection Prevents Missed Events
Reliable recovery requires retained event history and replay from an identifier or cursor.
Allowing Proxy Buffering for SSE
Buffered intermediaries can delay events instead of forwarding them as they are produced.
Polling a Database Repeatedly per Waiting Request
Large numbers of long-polling clients can create continuous database query load.
Sending Credentials in Query Strings
URLs can appear in logs, diagnostics and browser history.
Authorizing Only When the Connection Opens
Each subscription and sensitive command requires an authorization decision.
Ignoring Deployment Draining
Terminating instances without graceful connection handling can disconnect every attached client simultaneously.
Assuming Delivery Means Processing
Receiving an event at the client does not prove that the client applied the event successfully or exactly once.
Recommended Test Cases
| Test | Expected Evidence |
|---|---|
| WebSocket handshake | An authorized client establishes the intended protocol connection |
| Invalid Origin | The WebSocket handshake is rejected |
| Unauthorized subscription | The client cannot subscribe to another user's or tenant's channel |
| Oversized message | The message is rejected without uncontrolled allocation |
| Slow WebSocket client | The bounded backpressure policy is applied |
| SSE disconnect | The client reconnects according to policy |
| SSE replay | Events after the last processed identifier are returned |
| Long-poll timeout | The request completes cleanly without fabricating an event |
| Duplicate event | Idempotent client processing prevents duplicate effects |
| Instance shutdown | Connections drain or reconnect to healthy instances |
| Broker outage | The system fails safely and reports event-delivery degradation |
| Reconnection storm | Backoff, jitter and admission controls protect the service |
Best Practices
Recommended Practices
- Choose the simplest technique that meets the direction and latency requirements.
- Use secure transport for production connections.
- Authenticate every connection.
- Authorize every subscription, channel and command.
- Validate WebSocket Origin values.
- Define a versioned application message protocol.
- Assign unique identifiers to replayable events.
- Make event processing idempotent where duplicates are possible.
- Use bounded per-connection queues.
- Apply message-size and event-size limits.
- Use heartbeat and idle-timeout policies.
- Reconnect with exponential backoff and jitter.
- Design missed-event replay explicitly.
- Disable inappropriate intermediary buffering for SSE.
- Use a shared broker for events across application instances.
- Drain persistent connections during deployments.
- Monitor connections, queues, delivery latency and reconnect rates.
- Protect credentials, messages and diagnostic captures.
Practice Exercise
Build a secure WebSocket echo service and compare its behaviour with SSE and long polling.
Requirements
- Use
wss://for the WebSocket endpoint. - Authenticate the connection.
- Validate the browser Origin.
- Accept text messages up to a defined maximum size.
- Validate every message as structured JSON.
- Return the message with a server-generated identifier and timestamp.
- Support application-level heartbeat messages.
- Reject unsupported message types.
- Close idle connections according to policy.
- Reconnect the browser with exponential backoff and jitter.
- Create an SSE endpoint that streams server-generated status events.
- Create a long-polling endpoint using an event cursor.
- Test disconnect and replay behaviour.
- Compare connection count, event latency and request volume.
Comparison Template
| Measurement | WebSocket | SSE | Long Polling |
|---|---|---|---|
| Communication direction | Record evidence | Record evidence | Record evidence |
| Connection lifecycle | Record evidence | Record evidence | Record evidence |
| Average event latency | Record measurement | Record measurement | Record measurement |
| Requests per event | Record measurement | Record measurement | Record measurement |
| Reconnect behaviour | Record evidence | Record evidence | Record evidence |
| Missed-event recovery | Record evidence | Record evidence | Record evidence |
| Slow-client behaviour | Record evidence | Record evidence | Record evidence |
| Infrastructure compatibility | Record evidence | Record evidence | Record evidence |
Frequently Asked Questions
What is a WebSocket?
A WebSocket is a persistent framed communication protocol that allows client and server to send messages in both directions.
What is SSE?
Server-Sent Events provide a long-lived HTTP response through which a server streams UTF-8 text events to a client.
What is long polling?
Long polling keeps an HTTP request open until an event becomes available or a timeout occurs, after which the client sends another request.
Which technique supports bidirectional communication?
WebSocket provides bidirectional message communication over one persistent connection.
Can an SSE client send data to the server?
The EventSource stream carries events from server to client. The client can send commands through separate HTTP requests.
Does WebSocket automatically reconnect?
No. Browser applications normally implement their own reconnection, backoff and state-restoration logic.
Does SSE automatically reconnect?
EventSource includes browser-managed reconnection behaviour, but missed-event recovery still requires an application replay design.
Can WebSocket send binary data?
Yes. WebSocket supports text and binary application messages.
Can SSE send binary data directly?
SSE event streams are UTF-8 text. Binary information requires an application encoding or another transport.
Does message delivery guarantee exactly-once processing?
No. Applications need event identifiers, replay rules, duplicate handling and idempotent processing when delivery can be retried.
When should long polling be used?
Long polling can be considered when ordinary HTTP compatibility is more important than the efficiency of a persistent streaming or bidirectional protocol.
What comes after this topic?
This topic completes Networking and Web Request Lifecycle. The next module is API Design and Service Contracts, beginning with REST.
Key Takeaway
WebSockets provide persistent bidirectional message communication. SSE provides a simpler HTTP-based server-to-client text event stream with browser-managed reconnection. Long polling delays each HTTP response until an event or timeout and then repeats the request. Regardless of the technique, production systems need authentication, per-channel authorization, bounded queues, heartbeat and timeout policies, reconnection with backoff, missed-event replay, idempotent processing, shared event distribution and graceful connection draining.