Selkies

webrtc_signaling_server

WebRTC signaling: peer registry, session/room relay, and secure-mode gates.

Implements the WebSocket signaling plane the WebRTC streaming mode rides on. One in-process "server" peer owns the media graph; browser "client" peers (controllers and viewers, one set per display) pair with it through SESSION messages, or exchange ROOM messages for multi-peer rooms. Newest-connection-wins eviction mirrors websockets mode so a page refresh supersedes its own stale socket, with a takeover-storm breaker so two live auto-reconnecting pages cannot trade the session forever.

Wire protocol (text frames, space-separated): a peer opens with HELLO <server|client> [<json-metadata>] (client_type, client_slot, client_strict_viewer, client_token, server_token, display_id, display_position, fullcolor_codecs: the codec names the client decodes at 4:4:4, tenbit_codecs: the formats it decodes at 10 bits, a codec name for 4:2:0 and the name with 444 after it for 4:4:4, client_tab_id, cc_start_kbps: the rate congestion control last held the page's display at, page_size: the [width, height] its first resize will ask for, resume_key: a secret of the page's session) and is answered HELLO. A server that does not know a key ignores it. A client whose socket was cut with no close frame keeps its session for SESSION_HOLD_S: a hello naming its resume_key is answered RESUMED <callee-id> and carries on that session, under its old peer id, with what was addressed to it meanwhile; the media path never needed the socket. SESSION <peer-id|server> pairs the caller with the callee: the caller gets SESSION_OK <callee-id>, the callee SESSION_START <caller-id> <client_type> <display_id> <display_position> [<client_token>] [fullcolor=<codec,...>] [tenbit=<format,...>], and a disconnect sends the partner SESSION_END <peer-id> <client_type>. In a session every message is addressed <peer-id> <message> and relayed as <sender-id> <message>, only between session partners. ROOM <room-id> joins or creates a room (ROOM_OK <member-ids>, members get ROOM_PEER_JOINED / ROOM_PEER_LEFT <peer-id>), where ROOM_PEER_MSG <peer-id> <message> is relayed as ROOM_PEER_MSG <sender-id> <message>. Errors are ERROR <text>.

Concurrency model: all registry mutation happens under a single asyncio.Lock, and every socket send/close triggered while holding it is deferred and flushed after release, so one slow peer socket can never serialize other handshakes.

In secure mode (a master token is configured) the auth middleware forwards WebSocket upgrades without Basic auth, so the token checks here are the only gate: client peers must present a provisioned session token and server peers the master token itself. Token checks are constant-time lookups in the live control-plane table (/api/tokens), read per handshake.

attributeSERVER_PEER_SECRET
= secrets.token_urlsafe(32)
attributelogger
= logging.getLogger('signaling')
attributeSESSION_HOLD_S
= 3.0
attributeHELD_LINES_MAX
= 256
attributeMAX_PAGE_SIZE
= 8192
attributeHELLO_MAX_BYTES
= 16 * 1024
attributeDISPLAY_ID_RE
= re.compile('[A-Za-z0-9_-]{1,32}')

On this page

No Headings
Edit on GitHub