WebSocket is defined in RFC 6455 (2011). Unlike HTTP which sends data as plain text headers and body, WebSocket communicates through compact frames β€” binary packets with a precise bit-level structure.


The HTTP Upgrade Handshake

Every WebSocket connection starts as a normal HTTP/1.1 request. The client sends special headers asking to "upgrade" the protocol:

Step 1 β€” Client sends HTTP Upgrade request:

GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==
Sec-WebSocket-Version: 13

Step 2 β€” Server responds with 101 Switching Protocols:

HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: s3pPLMBiTxaQ9kYGzzhZRbK+xOo=

The Sec-WebSocket-Accept value is computed as:

base64( SHA-1( Sec-WebSocket-Key + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" ) )

This proves the server genuinely understands the WebSocket protocol.

After the 101 response, the TCP connection is repurposed. The HTTP handshake is over β€” both sides now speak WebSocket frames directly over the same socket. No more HTTP.


Anatomy of a WebSocket Frame

Each message is broken into one or more frames. Here is the binary structure of a frame:

Field Size Description
FIN 1 bit 1 = final fragment of the message
RSV1-3 3 bits Reserved for extensions (usually 000)
Opcode 4 bits Type of frame (text, binary, close, ping, pong)
MASK 1 bit Client→Server MUST always be masked
Payload len 7 bits 0–125 = length; 126 = next 2 bytes; 127 = next 8 bytes
Masking key 32 bits 4-byte XOR key (client frames only)
Payload variable Message bytes, XOR'd with masking key

Frame Opcodes β€” All Types

Opcode Name Description
0x0 Continuation A fragment continuing a previous fragmented message
0x1 Text UTF-8 encoded text data (most common)
0x2 Binary Raw binary β€” images, files, audio, etc.
0x8 Close Initiates graceful connection teardown
0x9 Ping Heartbeat request β€” peer MUST reply with Pong
0xA Pong Heartbeat reply to a Ping frame