-
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. Since 0.15.0 it is also the reference
implementation of the Custom Namespaces plugin contract.
-
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