roadrunner_ws (roadrunner v0.1.0)

View Source

WebSocket protocol primitives (RFC 6455 + RFC 7692).

Owns the protocol-level types (opcode/0, frame/0, close_code/0) referenced by roadrunner_ws_handler callback signatures, plus the permessage-deflate extension shape negotiated during the handshake.

The exported wire-level functions (frame parse/encode, handshake response builder, extension negotiation) are framework plumbing called from roadrunner_ws_session. They're not part of the documented public API — implement roadrunner_ws_handler to write WebSocket endpoints and let the framework deliver already-parsed frames.

Summary

Types

Close status codes a server is permitted to send per RFC 6455 §7.4. 1004/1005/1006 are reserved (MUST NOT appear on the wire); 1012/1013 are unassigned. 3000-3999 is the IANA-registered range, 4000-4999 is for application-private use.

Encode-side options for encode_frame/4.

A parsed WebSocket frame. payload is the post-unmask (and post-reassembly + post-inflate, when delivered to a handler) bytes the application should treat as the message body. rsv1 carries the RFC 7692 compression flag when permessage-deflate was negotiated; otherwise always false.

The outcome of extension negotiation during the upgrade handshake. none means no extension was offered or accepted; {permessage_deflate, Params, ResponseHeaderValue} means RFC 7692 was negotiated with the given parameters, and ResponseHeaderValue is the value placed in the response's Sec-WebSocket-Extensions header.

WebSocket frame opcodes (RFC 6455 §11.8). continuation only appears on the wire — the session reassembles fragmented messages before dispatching to roadrunner_ws_handler:handle_frame/2, so handlers see text or binary for data and ping/pong/close for control. Outbound replies use text, binary, ping, pong, or close.

Parse-side options for parse_frame/2.

Negotiated permessage-deflate parameters per RFC 7692 §7.1. Window-bits values are zlib's (8..15). The *_no_context_takeover flags mirror the request; when true, the corresponding zlib context is reset after every message.

Types

close_code()

-type close_code() :: 1000..1003 | 1007..1011 | 1014 | 3000..4999.

Close status codes a server is permitted to send per RFC 6455 §7.4. 1004/1005/1006 are reserved (MUST NOT appear on the wire); 1012/1013 are unassigned. 3000-3999 is the IANA-registered range, 4000-4999 is for application-private use.

encode_opts()

-type encode_opts() :: #{rsv1 => boolean()}.

Encode-side options for encode_frame/4.

  • rsv1 — set the RSV1 bit on the emitted frame. The caller is responsible for ensuring an extension that uses the bit is in effect (RFC 7692 permessage-deflate).

frame()

-type frame() :: #{fin := boolean(), rsv1 := boolean(), opcode := opcode(), payload := binary()}.

A parsed WebSocket frame. payload is the post-unmask (and post-reassembly + post-inflate, when delivered to a handler) bytes the application should treat as the message body. rsv1 carries the RFC 7692 compression flag when permessage-deflate was negotiated; otherwise always false.

negotiated()

-type negotiated() ::
          none | {permessage_deflate, permessage_deflate_params(), ResponseHeaderValue :: binary()}.

The outcome of extension negotiation during the upgrade handshake. none means no extension was offered or accepted; {permessage_deflate, Params, ResponseHeaderValue} means RFC 7692 was negotiated with the given parameters, and ResponseHeaderValue is the value placed in the response's Sec-WebSocket-Extensions header.

opcode()

-type opcode() :: continuation | text | binary | close | ping | pong.

WebSocket frame opcodes (RFC 6455 §11.8). continuation only appears on the wire — the session reassembles fragmented messages before dispatching to roadrunner_ws_handler:handle_frame/2, so handlers see text or binary for data and ping/pong/close for control. Outbound replies use text, binary, ping, pong, or close.

parse_opts()

-type parse_opts() :: #{allow_rsv1 => boolean(), pre_unmasked => binary()}.

Parse-side options for parse_frame/2.

  • allow_rsv1 — surface the RSV1 bit in the returned frame map. Set once permessage-deflate (RFC 7692) is negotiated. RSV2 and RSV3 are always rejected; no IETF extension uses them.
  • pre_unmasked — caller-supplied already-unmasked payload. When this matches the frame's length, parse_frame/2 skips its own unmask pass and uses the supplied bytes directly.

permessage_deflate_params()

-type permessage_deflate_params() ::
          #{server_max_window_bits := 8..15,
            client_max_window_bits := 8..15,
            server_no_context_takeover := boolean(),
            client_no_context_takeover := boolean()}.

Negotiated permessage-deflate parameters per RFC 7692 §7.1. Window-bits values are zlib's (8..15). The *_no_context_takeover flags mirror the request; when true, the corresponding zlib context is reset after every message.