Connection Establishment
The WebSocket handshake occurs over HTTP before upgrading to a persistent bidirectional connection.
Client Request
GET /realtime HTTP/1.1
Host: api.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: YnwxNDV0eGtleXBhc3M=
Sec-WebSocket-Version: 13
Upgrade: websocketsignals the intent to switch protocolsSec-WebSocket-Keycontains a random Base64-encoded value for server validationSec-WebSocket-Version: 13indicates the protocol version
Server Response
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: ZnJvemVuYmFzZTY0aGFzaA==
The Sec-WebSocket-Accept value is computed by concatenating the client's Sec-WebSocket-Key with the fixed string 258EAFA5-E914-47DA-95CA-C5AB0DC85B11, then applying SHA-1 hashing followed by Base64 encoding. Cross-origin requests require setting Access-Control-Allow-Origin headers on the server.
Once the handshake completes, the underlying TCP connection operates under WebSocket framing rules for all subsequent communication.
Status Codes Reference
Standard Close Codes
| Code | Constant | Description |
|---|---|---|
| 1000 | CLOSE_NORMAL |
Normal closure, purpose fulfilled |
| 1001 | CLOSE_GOING_AWAY |
Endpoint shutting down (navigation, server shutdown) |
| 1002 | CLOSE_PROTOCOL_ERROR |
Protocol violation or malformed data |
| 1003 | CLOSE_UNSUPPORTED |
Incompatible data type received |
| 1005 | CLOSE_NO_STATUS_RECEIVED |
No close code was transmitted (informational only) |
| 1006 | CLOSE_ABNORMAL |
Connection lost without close frame |
| 1007 | - | Payload not valid UTF-8 |
| 1008 | - | Message violates policy |
| 1009 | CLOSE_TOO_LARGE |
Message exceeds buffer capacity |
| 1011 | INTERNAL_ERROR |
Unexpected server condition |
| 1015 | - | TLS handshake failure |
Frequently Encountered in Practice
- 1000, 1001, 1005, 1006, 1015
Note that code 1005 is never transmitted over the wire—it exists for diagnostic purposes.
Keep-Alive Mechanisms
Application Layer Ping/Pong
The client sends periodic ping frames, and the server must respond with a pong frame containing identical application data. These frames cannot be fragmented and must be transmitted atomically.
TCP Keep-Alive
Since WebSocket operates atop TCP, the protocol's built-in keep-alive probes can detect connection health. The operating system sends periodic keep-alive packets when a connection sits idle—typically every 2 hours on both Linux and Windows. System parameters control this interval, and Nginx provides configuraton options to tune TCP probe timing.
Using application-layer ping/pong is preferred. TCP keep-alive adds indirect detection overhead and may produce unintended side effects.
Network Infrastructure Considerations
Firewalls, proxies, and routers often enforce idle connection timeouts. While application-layer keep-alive typically mitigates these issues, awareness of infrastructure-level timeout settings proves valuable during troubleshooting.
Connection Termination
Clean Shutdown
Both parties exchange 1000 status frames. The client sends one, the server responds with one, then the connection closes gracefully.
Endpoint Departure
Browser tab closure or navigation triggers code 1000 or 1001 depending on implementation. Most libraries treat these identically—both represent intentional closure.
Silent Disconnection
Code 1005 indicates an unobserved interruption without an error—commonly occurring during page refreshes. Applications typically do not handle this explicitly; reconnection logic handles it implicitly.
Abnormal Termination
Code 1006 signals an unclean disconnect.
Network failures (firewall blocks, proxy timeouts, TCP keep-alive expiration, infrastructure idle timeouts) generate TCP RST packets, immediately notifying both endpoints of the failure.
Process termination on either side—server crashes or browser process termination—causes the operating system to release resources via TCP RST, alerting the peer to the abrupt disconnection.
Libraries handle most disconnection scenarios automatically. Manual intervention focuses primarily on reconnection logic and cleanup of application state.