The WebSocket Handshake
A WebSocket does not appear out of thin air. It starts life as a perfectly ordinary HTTP request and is then upgraded in place. Understanding this handshake demystifies a great deal: why WebSockets travel on the same ports as web traffic, why they pass through most proxies and firewalls, and why the ws:// and wss:// schemes mirror http:// and https://.
It begins as HTTP
Section titled “It begins as HTTP”The client opens a normal TCP connection and sends an HTTP GET request — but with special headers that say “I would like to switch this connection to the WebSocket protocol.” The two headers that do the real work are Upgrade: websocket and Sec-WebSocket-Key.
GET /chat HTTP/1.1Host: example.comUpgrade: websocketConnection: UpgradeSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==Sec-WebSocket-Version: 13Origin: https://example.comA few of these earn their place:
Upgrade: websocketandConnection: Upgradetogether signal the protocol switch.Sec-WebSocket-Keyis a random, base64-encoded value the client generates fresh for this connection. It is not a security secret; it exists so the client can confirm the response came from a server that genuinely understood the WebSocket handshake.Sec-WebSocket-Version: 13pins the protocol version (13 is the standard one).
The 101 response
Section titled “The 101 response”If the server speaks WebSocket and accepts, it replies with status 101 Switching Protocols — an HTTP status that means exactly “we are done with HTTP semantics on this connection; from here on it is a different protocol.”
HTTP/1.1 101 Switching ProtocolsUpgrade: websocketConnection: UpgradeSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=The magic is in Sec-WebSocket-Accept. The server takes the client’s Sec-WebSocket-Key, appends a fixed, well-known string defined by the spec, hashes the result with SHA-1, and base64-encodes it. The client computes the same value and checks for a match. If they agree, the client knows it is talking to a real WebSocket server and not, say, a cache that blindly returned a 101. No match, no connection.
The handshake, in order
Section titled “The handshake, in order”sequenceDiagram participant C as Client participant S as Server C->>S: TCP connection established C->>S: GET /chat HTTP/1.1 (Upgrade: websocket, Sec-WebSocket-Key) Note over S: validate headers, compute Sec-WebSocket-Accept S-->>C: HTTP/1.1 101 Switching Protocols (Sec-WebSocket-Accept) Note over C,S: same TCP connection — now speaking WebSocket C->>S: data frame S->>C: data frame
Notice what the diagram does not show: a second connection. After the 101, the client and server keep using the same TCP connection they already had. Nothing is reopened. The HTTP request was simply the doorway; once through it, both sides stop exchanging HTTP messages and start exchanging WebSocket frames (the subject of the next lesson).
Why this design is clever
Section titled “Why this design is clever”Because the handshake is an HTTP request, a WebSocket connection can ride on ports 80 and 443 alongside normal web traffic, reuse existing TLS for wss://, and slip through the proxies and load balancers that already understand HTTP. The protocol gets the reach of the web for free, then sheds HTTP’s request/response model the instant it no longer needs it.