From HTTP/1.1 to WebSocket
Behind the magic, the WebSocket handshake is just an HTTP/1.1 GET with four critical headers: Upgrade: websocket, Connection: Upgrade, Sec-WebSocket-Key, and Sec-WebSocket-Version: 13. The server's job is to recognize them, compute a derived value, and respond with 101 Switching Protocols.
The Sec-WebSocket-Accept hash
The client sends a base64-encoded random nonce in Sec-WebSocket-Key. The server concatenates that with a fixed magic GUID (258EAFA5-E914-47DA-95CA-C5AB0DC85B11), takes the SHA-1, and returns the base64 of that hash in Sec-WebSocket-Accept. This proves the server actually understands the WebSocket protocol — a generic HTTP server cannot accidentally complete the handshake.
Optional handshake headers
Sec-WebSocket-Protocol negotiates a subprotocol like graphql-ws or mqtt. Sec-WebSocket-Extensions negotiates extensions, most commonly permessage-deflate for compression. Origin identifies the calling page — your server should validate it.