Selkies

websockets_mode

WebSockets streaming mode: the service that pairs pixelflux capture with WebSocket clients.

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 video stripes from pixelflux, 0x02 client mic PCM, WS_OPCODE_WEBCAM a webcam frame for the virtual camera, 0x05 a gzip wrapped control text, and WS_OPCODE_PADDING padding toward a page that sent _pad,1, which drops it unread (PathProbe). 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. An unchanged id is repeated as a heartbeat, so a client that has nothing new to ack is still told apart from one that has gone silent (_run_frame_backpressure_logic).

attributeBACKPRESSURE_ALLOWED_DESYNC_MS
= 250
attributeBACKPRESSURE_ACK_HOLD_S
= 0.1
attributeSTILL_SCREEN_GAP_SECONDS
= 1.0
attributeSTILL_RESUME_GRACE_SECONDS
= 1.0
attributeRTT_SAMPLE_SANE_MAX_MS
= 10000
attributeACK_HOLD_SLACK_MS
= 1.0
attributeSTALE_ACK_LOG_S
= 60.0
attributeBACKPRESSURE_CHECK_INTERVAL_S
= 0.5
attributePATH_HOLD_MAX_S
= 1.5
attributeLINK_QUEUE_MS
= 40.0
attributeLINK_MEASURE_BYTES
= 4096
attributeLINK_CARRIED_SHARE
= 0.8
attributeLINK_JITTER_GAIN
= 0.125
attributeLINK_ACK_HISTORY
= 64
attributeLINK_RISE_ACKS
= 4
attributeLINK_RISE_JITTER_MS
= 3.0
attributeLINK_RISE_LONE
= 4
attributeLINK_GAP_S
= 2 * BACKPRESSURE_CHECK_INTERVAL_S
attributeLINK_PATH_WINDOWS
= 3
attributeLINK_PATH_SENT
= 0.5
attributeWS_OPCODE_PADDING
= 7
attributePAD_STEP_S
= 0.02
attributePAD_PING_S
= 0.1
attributePAD_CHUNK_MIN
= 1200
attributePAD_CHUNK_MAX
= 256 * 1024
attributeMAX_UINT16_FRAME_ID
= 65535
attributeFRAME_ID_SUSPICIOUS_GAP_THRESHOLD
= MAX_UINT16_FRAME_ID // 2
attributeSTALLED_CLIENT_TIMEOUT_SECONDS
= 4.0
attributeSTRUCTURAL_CAPTURE_SETTINGS
= ('codec', 'use_cpu', 'cpu_encode_threading', 'video_fullframe', 'video_fullcolor', 'video_bit_depth', 'video_cbr_mode')
attributeSTALLED_CLIENT_REPROBE_SECONDS
= 2.0
attributeSEND_STALL_SECONDS
= 10.0
attributeSEND_PROBE_SECONDS
= 0.5
attributeVIDEO_RELAY_BUDGET_SECONDS
= 2.0
attributeVIDEO_RELAY_BUDGET_MIN_BYTES
= 4 * 1024 * 1024
attributeVIDEO_RELAY_SYNC_FLOOR_SECONDS
= 1.0
attributeVIDEO_RELAY_LOST_RECOVERY_SECONDS
= 1.0
attributeVIDEO_RELAY_ROOM_FRAMES
= 3
attributeVIDEO_RELAY_LAG_SECONDS
= 0.1
attributeVIDEO_RELAY_PING_SECONDS
= 0.05
attributeVIDEO_RELAY_SETTLE_SECONDS
= 3.0
attributeVIDEO_RELAY_REACH_FRAMES
= 5
attributeVIDEO_RELAY_FAR_FRAMES
= 12
attributeVIDEO_RELAY_FAR_SECONDS
= 1.0
attributeVIDEO_RELAY_ANCHORED_RECOVERY_SECONDS
= 4.0
attributeVIDEO_RELAY_ANCHOR_SECONDS
= 0.25
attributeVIDEO_RELAY_SENT_MEMORY
= 4096
attributeVIDEO_RELAY_WRAP_LEAD
= 2
attributeWIRE_H264
= 1
attributeWS_BULK_BACKLOG_BYTES
= 16 * 1024
attributeWS_BULK_BACKLOG_POLL_S
= 0.002
attributeRTT_SMOOTHING_SAMPLES
= 20
attributeAUDIO_RED_DISTANCE
= 2
attributeAUDIO_RED_SETTLE_S
= 1.0
attributePCMFLUX_HEALTH_INTERVAL_SECONDS
= 2.0
attributePCMFLUX_RESTART_FLOOR_SECONDS
= 30.0
attributeSENT_FRAME_TIMESTAMP_HISTORY_SIZE
= 1000
attributeVIEWER_RESUME_MIN_INTERVAL_S
= 1.0
attributeTARGET_FRAMERATE
= 60
attributeSECURE_INPUT_PREFIXES
= frozenset(('kd', 'ku', 'kh', 'kr', 'm', 'm2', 'co', 'cmd', 'sf', 'sfe', 'cws', 'cbs', 'cwd', 'cbd', 'cwe', 'cbe', 'cw', 'cb', 'cr', 'REQUEST_CLIPBOARD'))
attributeUINPUT_MOUSE_SOCKET
= settings.uinput_mouse_socket
attributeENABLE_CURSORS
= bool(settings.enable_cursors[0])
attributeDEBUG_CURSORS
= bool(settings.debug_cursors[0])
attributeENABLE_RESIZE
= bool(settings.enable_resize[0])
attributeAUDIO_CHANNELS_DEFAULT
= 2
attributeAUDIO_BITRATE_DEFAULT
= int(float(settings.audio_bitrate))
attributePIXELFLUX_VIDEO_ENCODERS
= ['jpeg', 'h264enc', 'h264enc-striped', 'h265enc', 'vp8enc', 'vp9enc', 'av1enc']
attributelogger_selkies_gamepad
= logging.getLogger('gamepad')
attributelogger_app
= logging.getLogger('ws')
attributelogger_app_resize
= logging.getLogger('display')
attributelogger_input_handler
= logging.getLogger('input')
attributelogger
= logging.getLogger('ws')
attributedata_logger
= logging.getLogger('ws')
attributeX11_CAPTURE_AVAILABLE
= True
attributePCMFLUX_AVAILABLE
= True
attributePCMFLUX_PLAYBACK_AVAILABLE
= True
attributeIS_WAYLAND
= bool(settings.wayland[0])
attributeCURSOR_SIZEOptional[int]
= settings.cursor_size if settings.cursor_size > 0 else None
attributeGPU_ID_DEFAULT
= _EXPLICIT_GPU_ID if _EXPLICIT_GPU_ID is not None and _EXPLICIT_GPU_ID >= 0 else 0
attributeupload_pathstr
= str(getattr(settings, 'file_manager_path', '') or '~/Desktop')
attributeupload_dir_pathOptional[str]
= os.path.expanduser(upload_path)
attributeclient_permissionsdict[Any, dict]
= {}
attributeWS_GZIP_MIN_BYTES
= 512
attributeWS_GZIP_OFFLOAD_BYTES
= 512 * 1024
attributeTOKENS_FILE_POLL_S
= 2.0

On this page

No Headings
Edit on GitHub