five-on-it / apps/server/src/rtc-worker
apps/server/src/rtc-worker
The RTC worker: a worker thread that holds the game server's WebRTC peer connections (werift, pure TypeScript: DTLS, SCTP and ICE in JavaScript), so the game thread never loads it nor spends its ticks on it. rtc-host.ts starts it on the first offer, with its configuration (RtcWorkerConfig); it runs RtcPeers on werift's peer connections and talks to the game thread in batches (rtc-wire.ts), one message per event-loop turn each way. The game server's bundle ships it as rtc-worker.mjs beside server.mjs (build/bundle-server.mjs).
A peer connection gathers its host candidates on the configured addresses (all the host's by default), binds its UDP port within the configured range and uses no STUN server (iceServers: []); the browser's checks give the server its peer-reflexive candidates. An error thrown in werift's callbacks is logged and the worker carries on: the peer it belonged to times out and its client falls back to the WebSocket.
Two quirks of werift 0.24.4 matter here. Its DTLS numbers the first records after the handshake from 0 again, so one of them repeats the number of its Finished record and Chromium's replay window drops it: one early message of every channel was lost (the fourth, in every run with Chromium). skipFinishedRecord moves the count past it once the DTLS connects. And its SCTP never gives a message up when maxRetransmits is 0 (nor when maxPacketLifeTime is set): the server's side is created with one resend at most (rtc-host.ts' SERVER_RETRANSMITS), so a frame lost is resent once and then let go (the acked snapshots never need it); the page's side does not resend at all (@foi/protocol's RTC_CHANNEL).