-
Notifications
You must be signed in to change notification settings - Fork 0
Remote Namespace
The /remote socket.io namespace provides one-time-ticket binary
streaming sessions — built for remote-control use cases: an agent
streams binary frames (e.g. screen captures) to viewers, and viewers send
input events back to the agent.
-
An authenticated client on the main namespace requests a ticket:
client → server: REMOTE_TICKET_REQUEST { session_id?, machine_id?, role: 'agent'|'viewer' } server → client: REMOTE_TICKET { ok, session_id, ticket, role, expires_in }With auth enabled, the socket must authenticate first; the ticket inherits the socket's realm. Tickets are single-purpose, random, and expire after 60 s by default (
remote: { ticket_ttl_ms }). -
The remote party connects to
/remoteand presents the ticket:socket → server: auth { ticket, session_id } server → socket: auth_ok { session_id, role } | auth_error { message } // invalid/expired/mismatchedThe ticket must match the session and the role it was issued for.
-
Relay (0.14.3: rule-table driven, extensible without server changes):
Event Direction Payload frameagent → all viewers binary (Buffer/ArrayBuffer) frame data input.mouse/input.keyboardviewer → agent input event object input.sasviewer → agent secure-attention (Ctrl-Alt-Del) request remote.setmonitorviewer → agent multi-monitor switch request rtc.offeragent → viewers WebRTC SDP offer (agent is the offerer) rtc.answer/rtc.readyviewer → agent SDP answer / "viewer subscribed, send the offer" rtc.iceboth → opposite role trickle ICE candidates any other event sender → opposite role relayed verbatim (catch-all) One agent per session, any number of viewers; everything is scoped to the session's two rooms. The
rtc.*events are the WebRTC signaling bus: the session can negotiate a peer-to-peer DataChannel and move frames/input off the relay, falling back to it when P2P fails.The catch-all relays events with no rule to the opposite role's room, so new event names work with zero server changes. Reserved names (
auth,auth_ok,auth_error, socket.io internals) are never relayed — a party cannot forge server control events.
The rule table is operator-extensible via the hot-reloadable remote
settings block (applies within ~1 s, no restart):
"remote": {
"relay": {
"clipboard.set": { "from": "viewer", "to": "agent" },
"input.sas": { "enabled": false }
},
"relay_unlisted": "opposite"
}- Rule fields:
from(agent/viewer/any— sender role guard),to(agent/viewers/opposite),enabled: falseto drop. -
relay_unlisted:"opposite"(default) or"off"for a strict allow-list. - Settings are deep-merged: re-enabling a disabled event needs an explicit
"enabled": true. - Acknowledgement callbacks are stripped before re-emit; multi-argument payloads relay intact.
Server-side:
server.remote.getSession(sessionId); // { session_id, agent_connected, viewer_count }
server.remote.listSessions();
server.remote.issueTicket({ session_id, realm, machine_id, role });- Tickets are the only way into
/remote— there is no password fallback. - Issuing a ticket requires an (authenticated, when auth is on) main- namespace connection, so realm/role policy gates who can start sessions.
- Expired or reused-for-the-wrong-session tickets are rejected with
auth_error.
tyo-mq · README · Improvement Plan · Clustering Guide · Apache-2.0
Basics
Security
- Authentication and Realms
- Ephemeral Realms
- Roles and Connection Authorization
- Authorization Requests
Delivery
Routing
Operations
Reference