Namespace Reportman.Hub.Client.DataChannel
Classes
QueryProgress
Snapshot of the current phase of an in-flight SQL operation, suitable for binding to UI text near the busy indicator. The Agent emits its own 1Hz pulse over the DataChannel; this struct mirrors that into a single observable shape.
WebRtcChannelPool
Caches one open WebRtcDataChannelSession per Hub database so successive SQL queries on the same database reuse the negotiated peer connection. Without the pool every query pays the full ~1–3s setup cost (STUN gather + signaling + ICE checks + DTLS + SCTP). With the pool the first query is unchanged, all subsequent queries cost ~50–100 ms (just one DataChannel message round-trip).
Lifecycle of a pooled session (three concurrent timers — none of them holds the channel open "forever"):
- Idle timeout (default 60 s): closes when no
ExecuteAsynchas been issued for that long. Matches typical residential NAT UDP binding TTL — past this point the warm channel wouldn't be useful even if we kept it. - Max lifetime (default 10 min): absolute cap regardless of use. Prevents stale DTLS state and rotates the channel periodically.
- Keepalive ping (default every 25 s): sends a tiny "ping" message on the DataChannel. The Agent ack'es with "pong"; the outbound UDP packet alone refreshes the NAT mapping so the channel keeps working past the router's idle binding TTL.
Also evicts when the channel is observed dead (DTLS failure, Agent closed it, peer state change). The next caller gets a freshly negotiated session transparently.
WebRtcDataChannelSession
One-shot WebRTC peer for a single SQL operation against an Agent.
Lifecycle (per the per-SQL token decision):
- POST /api/data-session/start (Bearer + agentApiKey) → sessionId + JWT + iceServers.
- Open WS /api/data-session/{sessionId}/signal?token=jwt.
- Build RTCPeerConnection, create a DataChannel, generate offer, wait for ICE gather complete, forward offer over the signaling WS. The Hub routes it to the Agent and the answer comes back wrapped in {"source":"hub","body":"<agent reply json>"}.
- setRemoteDescription(answer), wait DC open (≤10s).
- Send {requestId, action, data} on the DC, collect executing / fetching / data / done messages, return the deserialized payload.
- Close the DC + peer + signaling WS; the session dies with the SQL.
If anything fails before DataChannelReadyAsync returns true,
the caller falls back to the existing HTTP path.
Enums
ConnectionMode
Effective transport for the most recent SQL operation. Surfaced to the UI as a chip next to the busy indicator.
QueryPhase
The sequential stages a single SQL operation passes through, from connecting and preparing through fetching, transfer and decoding to completion.