The upgrade, and the frames after it
A WebSocket does not start as a WebSocket. It starts as an ordinary HTTP/1.1 GET on port 443, with a few fields that ask the server to stop speaking HTTP.
GET /chat HTTP/1.1Host: example.comUpgrade: websocketConnection: UpgradeSec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==Sec-WebSocket-Version: 13 HTTP/1.1 101 Switching ProtocolsUpgrade: websocketConnection: UpgradeSec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo= That blank line after the 101 is the same framing device from track 4, doing its last
job: it is the exact byte at which HTTP ends and frames begin.
Why it looks like HTTP at all
Because that is what deploys. A WebSocket connection traverses corporate proxies, load balancers and firewalls that have never heard of WebSockets, precisely because the first thing they see is a GET to port 443 with a Host field.
Sec-WebSocket-Accept is the server hashing the client's key together with a fixed,
published GUID. It is not a secret and proves nothing about identity — it is a proof of
comprehension, showing that whatever answered actually understood the request rather
than a cache replaying an old 101.
Frames, and the message that spans several
After the 101 there is no request/response pairing at all — just two independent
streams of frames sharing one socket. A frame is a couple of bytes of
header and then payload, which is why a chat message costs about eleven bytes total.
A message is not a frame. A sender that does not yet know how long its message will be can start sending anyway: the first frame carries the type with FIN clear, every frame after it carries the continuation opcode, and the last one sets FIN.
The length field has three encodings — 0–125 inline, then 126 meaning "the real length is in the next two bytes" and 127 meaning "the next eight" — and the encoding must be minimal, because two legal spellings of one frame is how parsers come to disagree.
Key takeaways
- A WebSocket begins as an ordinary GET on port 443, which is exactly why it deploys through infrastructure that knows nothing about it.
- The blank line ending the 101 response is the precise byte where HTTP stops and framing begins.
- Sec-WebSocket-Accept proves comprehension, not identity — the GUID it hashes is published in the RFC.
- After the upgrade there is no request/response pairing: two independent streams of frames share one socket.
- A message may span several frames, and binary frames exist so bytes need not be base64-encoded into text ones.