C.W.K.
Stream
Lesson 08 of 08 · published

Connection Lifecycle & Frame Format

~13 min · foundations, frames, close-codes

Level 0Poller
0 XP0/60 lessons0/10 achievements
0/120 XP to next level120 XP to go0% complete

Lifecycle as a state machine

A WebSocket connection moves through four states: CONNECTING (handshake in flight) → OPEN (frames flowing) → CLOSING (one side sent close, the other is acknowledging) → CLOSED (terminal). The browser exposes these as WebSocket.readyState values 0/1/2/3.

The frame

WebSocket data is not a stream of bytes — it is a sequence of frames. Each frame has a small header (2-14 bytes) carrying: a FIN bit (last frame of a message?), an opcode (text, binary, ping, pong, close, or continuation), a mask bit, and the payload length. Client-to-server frames are always masked with a per-frame XOR key; server-to-client frames are not. This masking is anti-cache-poisoning, not security — do not confuse it with encryption.

Close codes

Every clean close carries a code. 1000 is a normal close. 1001 is "going away" (server shutdown, page navigation). 1006 is the special abnormal-close code reserved for "the connection died and no close frame was received." 4000-4999 is reserved for application-defined codes — use them for "session expired", "kicked from room", and so on.

Code

RFC 6455 frame layout·text
 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-------+-+-------------+-------------------------------+
|F|R|R|R| opcode|M| Payload len |    Extended payload length    |
|I|S|S|S|  (4)  |A|     (7)     |            (16/64)            |
|N|V|V|V|       |S|             |   (if payload len==126/127)   |
| |1|2|3|       |K|             |                               |
+-+-+-+-+-------+-+-------------+-------------------------------+
|     Extended payload length continued, if payload len == 127  |
+---------------------------------------------------------------+
|                          Masking-key                          |
+---------------------------------------------------------------+
|                          Payload data ...                     |
+---------------------------------------------------------------+
Opcode reference·text
0x0  continuation  - more of a fragmented message
0x1  text          - UTF-8 payload
0x2  binary        - bytes
0x8  close         - graceful shutdown
0x9  ping          - heartbeat request (RFC-level)
0xA  pong          - heartbeat response (RFC-level)
Common close codes·text
1000  Normal closure        - clean shutdown
1001  Going away            - server shutting down or tab navigated
1002  Protocol error        - malformed frame
1003  Unsupported data      - text on a binary endpoint, e.g.
1006  Abnormal closure      - no close frame received (drop)
1008  Policy violation      - server-defined refusal
1009  Message too big
1011  Internal server error
4000-4999  Application use  - your codes (auth expired, room full, ...)

External links

Exercise

Run a small WebSocket client, capture frames with Wireshark or browser devtools. Send a text message; observe the masked client-to-server frame. Receive an echo; observe the unmasked server-to-client frame. Now close the tab abruptly mid-conversation — confirm the server-side log shows close code 1006, not 1000.

Progress

Progress is local-only — sign in to sync across devices.
Spotted a bug or have feedback on this page?Report an Issue

Comments 0

🔔 Reply notifications (sign in)
Sign inPlease sign in to comment.

No comments yet — be the first.