Skip to content
Language:en Author:Laborci Gergely
realtime

WebSocket: Connection Setup, Frames and Two-Way Messages

Objectives

By the end of the lesson, you can explain how a WebSocket connection is set up, the role of frames and messages, the purpose of masking and the control frames, and say what the protocol does not give.

Why is it needed?

The earlier methods are either a new exchange per request (polling, long polling) or a one-way stream (SSE). If both parties initiate frequently, it is practical to exchange two-way messages on the same connection. According to MDN, the WebSocket API makes it possible to open a two-way interactive communication session between the browser and a server, without having to poll the server for a reply.

Connection setup (handshake)

The connection starts with an HTTP request in which the client asks for a protocol switch. According to RFC 6455 the request is a GET, at least HTTP/1.1, and contains the Upgrade: websocket and Connection: Upgrade headers, a randomly chosen Sec-WebSocket-Key and Sec-WebSocket-Version: 13; from a browser the Origin also appears. The server accepts with a 101 Switching Protocols response, and computes the Sec-WebSocket-Accept value by appending a fixed GUID (Globally Unique Identifier, 258EAFA5-E914-47DA-95CA-C5AB0DC85B11) to the key, taking a SHA-1 (Secure Hash Algorithm 1) digest and base64-encoding it. With the RFC's example key (dGhlIHNhbXBsZSBub25jZQ==) the result is s3pPLMBiTxaQ9kYGzzhZRbK+xOo=.

sequenceDiagram
  participant C as Browser
  participant P as Reverse proxy
  participant S as WebSocket server
  C->>P: GET + Upgrade: websocket
  P->>S: Forward the handshake
  S-->>P: 101 Switching Protocols
  P-->>C: Connection established
  C->>S: Message
  S->>C: Message

The ws scheme is unencrypted, wss means a TLS-protected connection; according to the RFC the default ports are 80 and 443. According to MDN, browsers generally require a secure connection, and unusual ports can cause trouble with firewalls and proxies.

Under HTTP/2 and HTTP/3 the setup is different: RFC 8441 carries the WebSocket onto a single HTTP/2 stream with the "extended CONNECT" method (the :protocol pseudo-header, the SETTINGS_ENABLE_CONNECT_PROTOCOL setting), and RFC 9220 adapts the same to HTTP/3. In that case there is no Upgrade and no 101. The support of the proxy and the server must be checked.

Frames and messages

The protocol carries data in frames; one application message can be split into several frames (fragmentation). Text (UTF-8) and binary messages can be sent. The browser API offers a message-based interface, so the incoming byte stream need not be split with own framing, as with a raw TCP (Transmission Control Protocol) protocol.

Masking. According to RFC 6455, the client must mask every frame it sends, the server must not, and the server must close the connection if it receives an unmasked frame. The purpose of masking, according to RFC section 10.3, is protection against the poisoning of intermediary proxies' caches: the remote script must not be able to control how the data appears on the wire. It is not encryption; confidentiality and integrity are provided by TLS (wss) (RFC 10.6).

Control frames. The Close, Ping and Pong frames can carry at most 125 bytes of payload and cannot be fragmented. The other party must answer a Ping with a Pong echoing the Ping's data; this can be used as a heartbeat and for checking the connection. In an orderly close the Close frame can carry a status code: according to the RFC 1000 is a normal closure, 1001 is "going away" (for example a server shutting down or a page being left), and 1006 is a reserved value that is never sent and indicates that the connection closed abnormally without a Close frame. The browser JavaScript WebSocket API provides no method for sending a Ping directly, so where necessary an application-level heartbeat is used (10.3).

Subprotocol

According to the RFC, the client can list the subprotocols it supports in the Sec-WebSocket-Protocol header, and the server selects one (or none) and sends it back. The subprotocol names the message format and the rule set. WebSocket itself does not define what "login", "subscription" or "booking" is: the application message schema describes that (10.2).

Characteristics

Aspect WebSocket
Direction Two-way
Initiator The client opens the connection; afterwards either side may send
Connection persistence Persistent until either side or the network breaks it
Latency Low: no per-request header and connection setup
Load An open connection per client (memory, file descriptor); low cost per message
Fault tolerance The application must handle interruption and message loss (10.3)
When it fits Frequent two-way message exchange: shared editing, chat, control, games
When it does not Rare, server-to-client-only notification (SSE or polling is simpler); cacheable resource reads

Common misconceptions

Statement Clarification
"A WebSocket is an HTTP connection." It starts with an HTTP request, but afterwards it is a protocol with its own framing.
"Masking encrypts." No; confidentiality is provided by TLS (wss).
"A WebSocket always starts with 101." Under HTTP/2 and HTTP/3 extended CONNECT is the basis.
"An open connection = a successful operation." The transport and the application state are separate.

In short

  • A WebSocket starts with an HTTP request, switches protocol (HTTP/1.1: 101), then carries messages in frames.
  • The client masks every frame; this is not encryption.
  • The control frames (Ping/Pong/Close) give a keep-alive and an orderly close.
  • The meaning of messages and durability must be devised by the application.

Review questions

  1. What does WebSocket provide, and what must the application define?
  2. Why is masking not encryption?
  3. Why does an open connection not prove a successful operation?

Learning resources

Prerequisites (2)

  • SSE
  • long polling

Teaches (1)

  • WebSocket