Skip to content

WebSocket Multiplex

The agent communicates with the platform using a single outbound WebSocket connection that multiplexes HTTP requests and responses.

Why multiplex?

KVM devices are typically behind NATs or firewalls. Opening inbound ports is impractical (and a security risk). Instead, the agent opens a single outbound WSS connection and keeps it alive. The platform sends HTTP requests through this tunnel, and the agent proxies them to the local KVM web UI.

This means:

  • No port forwarding or VPN needed
  • Works behind corporate firewalls (outbound 443 is almost always open)
  • Single connection for heartbeats, console traffic, and control messages

Protocol

sequenceDiagram
    participant P as Platform
    participant A as Agent
    participant K as KVM Web UI

    Note over P,A: WSS connection (agent-initiated)

    P->>A: {type: "http_request", id: "r1", method: "GET", path: "/", headers: {...}}
    A->>K: GET http://localhost:8080/
    K-->>A: 200 OK + HTML body
    A-->>P: {type: "http_response", id: "r1", status: 200, headers: {...}, body: "..."}

    Note over P,A: Multiple requests can be in-flight simultaneously

    P->>A: {type: "http_request", id: "r2", ...}
    P->>A: {type: "http_request", id: "r3", ...}
    A-->>P: {type: "http_response", id: "r3", ...}
    A-->>P: {type: "http_response", id: "r2", ...}

Message types

Type Direction Description
heartbeat Agent -> Platform Sent every 15s. Includes health metrics (uptime, CPU, memory).
http_request Platform -> Agent HTTP request to proxy to the local KVM web UI.
http_response Agent -> Platform Response from the local KVM web UI.
session_open Platform -> Agent Notification that a console session has started.
session_close Platform -> Agent Notification that a console session has ended.

Request multiplexing

Each request has a unique id. Multiple requests can be in-flight simultaneously — the agent processes them concurrently using goroutines. Responses are matched by id, not by order.

This is critical for console sessions where the browser makes many parallel requests (HTML, JS, CSS, WebSocket upgrade for video stream).

Connection lifecycle

  1. Connect: Agent opens WSS to wss://app.kvmfleet.io/v1/agent/ws
  2. Authenticate: First message includes the device auth token
  3. Heartbeat loop: Agent sends heartbeats every 15 seconds
  4. Reconnect: On disconnect, agent uses exponential backoff (1s, 2s, 4s, ... up to 60s)

Video streaming

KVM video streams (MJPEG or H.264 via WebSocket) are proxied through the same tunnel. The agent upgrades the inner connection to a WebSocket when the KVM web UI requests it, and frames are forwarded bidirectionally over the outer WSS connection.