Tags: websocket, real-time, networking, protocols, http, tcp, full-duplex
Level: intermediate
TL;DR: Full-duplex, persistent communication channel over a single TCP connection initiated via an HTTP 101 Switching Protocols upgrade handshake.
Operates over TCP, keeping a single persistent connection open for bidirectional data flow.
Starts with an HTTP GET request containing Upgrade: websocket and Connection: Upgrade headers.
Server accepts the handshake by responding with HTTP status code 101 Switching Protocols.
Uses ws:// for unencrypted traffic (port 80) and wss:// for TLS-encrypted traffic (port 443).
Exchanges lightweight data frames rather than heavy HTTP request-response headers.
Supports UTF-8 text frames and binary frames (ArrayBuffer, Blob).
Maintains keep-alive state and detects dropped clients via control frames: Ping (0x9) and Pong (0xa).
Reduces latency and network overhead compared to periodic HTTP polling or long polling.
Handled at Layer 7; traverse proxies, firewalls, and load balancers through standard HTTP/HTTPS ports.
Q: How does a WebSocket connection differ from HTTP long-polling and Server-Sent Events (SSE)?R: HTTP long-polling holds requests open and re-establishes connections repeatedly, adding header overhead. SSE provides unidirectional server-to-client streaming over standard HTTP. I use WebSocket when I need low-latency, bidirectional communication.
Q: How do you scale a WebSocket application horizontally across multiple backend servers?R: I place a reverse proxy with sticky sessions at the edge and use a Pub/Sub layer like Redis or Kafka to broadcast messages between instances.
Q: How do you handle authentication securely in WebSockets?R: I authenticate during the initial HTTP upgrade handshake using HTTP-only cookies or a short-lived ticket query parameter, validating credentials before upgrading the socket.
Silent connection drops caused by intermediate proxies closing idle TCP connections without ping/pong heartbeats.
Sending authentication tokens in cleartext query parameters that get logged by reverse proxies.
Lack of backpressure management leading to unbounded memory growth on fast-producing servers or slow-consuming clients.
Forgetting to handle reconnection logic with exponential backoff and jitter on the client.
Missing sticky sessions on layer 7 load balancers when performing the initial upgrade handshake in a clustered environment.
// Native browser client with heartbeat and reconnection
class RealtimeClient {
private socket: WebSocket | null = null;
private pingInterval: number | null = null;
connect(url: string): void {
this.socket = new WebSocket(url);
this.socket.onopen = () => {
this.pingInterval = window.setInterval(() => {
if (this.socket?.readyState === WebSocket.OPEN) {
this.socket.send(JSON.stringify({ type: 'ping' }));
}
}, 30000);
};
this.socket.onmessage = (event: MessageEvent<string>) => {
const data = JSON.parse(event.data);
if (data.type !== 'pong') {
console.log('Received:', data);
}
};
this.socket.onclose = () => {
if (this.pingInterval) clearInterval(this.pingInterval);
setTimeout(() => this.connect(url), 5000);
};
}
send(payload: unknown): void {
if (this.socket?.readyState === WebSocket.OPEN) {
this.socket.send(JSON.stringify(payload));
}
}
}
[ ] Frame structure details (FIN bit, opcode, masking key for client-to-server frames)
[ ] Backpressure mechanisms and buffer monitoring via bufferedAmount
[ ] Horizontal scaling strategies using Redis Pub/Sub adapters
[x] HTTP 101 Switching Protocols upgrade handshake flow
[x] Protocol differences: WebSocket vs SSE vs HTTP/2 Server Push vs WebTransport
RFC 6455: The WebSocket Protocol
MDN Web Docs: The WebSocket API
WHATWG HTML Specification: Web sockets