Class 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.
Inheritance
WebRtcDataChannelSession
Assembly: Reportman.DataChannel.dll
Syntax
public sealed class WebRtcDataChannelSession : IAsyncDisposable
Properties
View Source
IsAlive
True when the negotiated DataChannel is open and the session hasn't
been disposed. The pool reads this to decide whether to reuse the
cached session or evict it and open a fresh one.
Declaration
public bool IsAlive { get; }
Property Value
View Source
IsBusy
True while at least one ExecuteAsync(string, object, CancellationToken) is in flight. The
pool reads this in its idle/max-life check to avoid evicting a session
whose query is still running — without this guard a query lasting
longer than the pool's idle window (60s) or max-lifetime (10min)
would be killed mid-flight as the timer fires against a session
whose Touch() only ran at the start of the request.
Declaration
public bool IsBusy { get; }
Property Value
View Source
Mode
Declaration
public ConnectionMode Mode { get; }
Property Value
Methods
View Source
DisposeAsync()
Declaration
public ValueTask DisposeAsync()
Returns
View Source
ExecuteAsync(string, object, CancellationToken)
Sends a single {requestId, action, data} request on the live
DataChannel and returns the fully reassembled payload bytes. The
caller decodes them per action: SQL-shaped actions get
FastSerializer-binary bytes; metadata actions get UTF-8 JSON bytes.
Progress messages from the Agent are surfaced via the constructor's
onProgress callback. A 15s gap without any message from the Agent
throws — the request is considered dead.
Declaration
public Task<byte[]> ExecuteAsync(string action, object data, CancellationToken ct)
Parameters
Returns
View Source
SendKeepaliveAsync(CancellationToken)
Sends a tiny ping over the DataChannel and waits briefly for the pong.
Used by the pool to keep the NAT mapping warm during idle windows so
the next real query doesn't pay the full STUN/ICE/DTLS setup cost.
Returns true if the channel was alive at send time (pong arrival is
not strictly required — the outbound UDP packet alone refreshes the
router's binding).
Declaration
public Task<bool> SendKeepaliveAsync(CancellationToken ct = default)
Parameters
Returns
View Source
TryOpenAsync(HttpClient, Uri, string?, object, Action<QueryProgress>?, CancellationToken)
Attempts to negotiate a fresh DataChannel. startBody
is the JSON body for POST /api/data-session/start; accepts either
new { agentApiKey } or new { hubDatabaseId }. Returns null
on any failure; the caller should then fall back to the HTTP path.
Declaration
public static Task<WebRtcDataChannelSession?> TryOpenAsync(HttpClient http, Uri apiBaseUri, string? bearer, object startBody, Action<QueryProgress>? onProgress, CancellationToken ct)
Parameters
Returns
Events
View Source
DiagnosticLog
Raised for every direct-channel negotiation trace line. A UI host (e.g.
the Designer's "Net Log" tab) can subscribe to surface the handshake
live: iceServers, candidates exchanged, answer arrival, peer state and
where it threw. Fired on whatever thread produced the line (often a
SIPSorcery worker) — subscribers must marshal to their UI thread.
Static because sessions are created deep inside the engine
(DirectAgentExecutor) with no handle to the UI.
Declaration
public static event Action<string>? DiagnosticLog
Event Type
Implements