selkies
WebSockets-mode streaming server: the main Selkies application module.
Owns the data WebSocket plane for the websockets transport: per-client connection handling (auth/roles, input dispatch, settings), the per-display pixelflux video captures with their bounded per-client relays, the shared pcmflux Opus audio fan-out (with the all-clients Opus+RED gate), microphone forwarding, clipboard/cursor delivery, stats collection, and the display layout/reconfiguration engine shared conceptually with the WebRTC transport (parity between the two transports, and between X11 and Wayland, is a design requirement).
Threading model: one asyncio event loop runs everything control-plane.
pixelflux/pcmflux deliver frames from their own native threads; those
callbacks never touch asyncio state directly — they hand zero-copy items to
the loop via call_soon_threadsafe. Per-client video delivery is bounded
by _VideoRelay (drop-and-resync past a byte budget) and audio by a fixed
queue, so one slow client can never back pressure the shared pipeline.
Blocking native calls (capture start/stop, geometry reads) run on executor
threads. The Wayland path is subprocess-free by design: compositor output
management, DPI-as-output-scale, and cursor sizing all go through the
in-process pixelflux handle, never through forked tools.
Wire framing: text frames carry the control verbs; binary frames are typed
by their first byte — 0x01 Opus audio (pcmflux's native header, sent as-is),
0x03 JPEG and 0x04 H.264 video stripes from pixelflux, 0x02 client mic PCM,
WS_OPCODE_WEBCAM a webcam frame for the virtual camera, and 0x05 a gzip
wrapped control text. A client that sends _gz,1 can inflate gzip: control
text at or above WS_GZIP_MIN_BYTES then goes out as 0x05 frames (small,
latency-critical messages such as input stay raw), and the server echoes the
verb so the client gzips its own large sends, which the handler inflates
back into text before dispatch. Video chunks carry a uint16 frame id that
the display's owning client acknowledges (CLIENT_FRAME_ACK); the ack
cadence sizes that display's backpressure window and the matched send
stamps feed its smoothed RTT.
attributeBACKPRESSURE_ALLOWED_DESYNC_MS= 2000attributeBACKPRESSURE_LATENCY_THRESHOLD_MS= 50attributeBACKPRESSURE_LATENCY_FORGIVENESS_MAX_MS= 1000attributeRTT_SAMPLE_SANE_MAX_MS= 10000attributeBACKPRESSURE_CHECK_INTERVAL_S= 0.5attributeMAX_UINT16_FRAME_ID= 65535attributeFRAME_ID_SUSPICIOUS_GAP_THRESHOLD= MAX_UINT16_FRAME_ID // 2attributeSTALLED_CLIENT_TIMEOUT_SECONDS= 4.0attributeSHARED_STREAM_SEND_TIMEOUT_SECONDS= 1.0attributeVIDEO_RELAY_BUDGET_SECONDS= 2.0attributeVIDEO_RELAY_BUDGET_MIN_BYTES= 4 * 1024 * 1024attributeVIDEO_RELAY_SYNC_FLOOR_SECONDS= 1.0attributeRTT_SMOOTHING_SAMPLES= 20attributeAUDIO_RED_DISTANCE= 2attributePCMFLUX_HEALTH_INTERVAL_SECONDS= 2.0attributePCMFLUX_RESTART_FLOOR_SECONDS= 30.0attributeSENT_FRAME_TIMESTAMP_HISTORY_SIZE= 1000attributeVIEWER_RESUME_MIN_INTERVAL_S= 1.0attributeTARGET_FRAMERATE= 60attributeUINPUT_MOUSE_SOCKET= settings.uinput_mouse_socketattributeENABLE_CURSORS= bool(settings.enable_cursors[0])attributeDEBUG_CURSORS= bool(settings.debug_cursors[0])attributeENABLE_RESIZE= bool(settings.enable_resize[0])attributeAUDIO_CHANNELS_DEFAULT= 2attributeAUDIO_BITRATE_DEFAULT= int(float(settings.audio_bitrate))attributePIXELFLUX_VIDEO_ENCODERS= ['jpeg', 'h264enc', 'h264enc-striped']attributeLOGLEVEL= logging.INFOattributelogger_selkies_gamepad= logging.getLogger('selkies_gamepad')attributelogger_app= logging.getLogger('app')attributelogger_app_resize= logging.getLogger('app_resize')attributelogger_input_handler= logging.getLogger('input_handler')attributelogger= logging.getLogger('main')attributedata_logger= logging.getLogger('data_websocket')attributeX11_CAPTURE_AVAILABLE= TrueattributePCMFLUX_AVAILABLE= TrueattributePCMFLUX_PLAYBACK_AVAILABLE= TrueattributeIS_WAYLAND= bool(settings.wayland[0])attributeCURSOR_SIZEOptional[int]= settings.cursor_size if settings.cursor_size > 0 else NoneattributeGPU_ID_DEFAULT= _EXPLICIT_GPU_ID if _EXPLICIT_GPU_ID is not None and _EXPLICIT_GPU_ID >= 0 else 0attributeupload_pathstr= str(getattr(settings, 'file_manager_path', '') or '~/Desktop')attributeupload_dir_pathOptional[str]= os.path.expanduser(upload_path)attributeuser_tokensdict[str, dict]= {}attributeclient_permissionsdict[Any, dict]= {}attributeactive_mk_tokenOptional[str]= Noneattributewebrtc_reconcile_hookOptional[Callable[[], Awaitable[None]]]= NoneattributeWS_GZIP_MIN_BYTES= 512attributeWS_GZIP_OFFLOAD_BYTES= 512 * 1024