Search Results for

    Show / Hide Table of Contents

    Class WebRtcDataChannelSession

    One-shot WebRTC peer for a single SQL operation against an Agent.

    Lifecycle (per the per-SQL token decision):

    1. POST /api/data-session/start (Bearer + agentApiKey) → sessionId + JWT + iceServers.
    2. Open WS /api/data-session/{sessionId}/signal?token=jwt.
    3. 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>"}.
    4. setRemoteDescription(answer), wait DC open (≤10s).
    5. Send {requestId, action, data} on the DC, collect executing / fetching / data / done messages, return the deserialized payload.
    6. 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
    object
    WebRtcDataChannelSession
    Implements
    IAsyncDisposable
    Inherited Members
    object.GetType()
    object.ToString()
    object.Equals(object)
    object.Equals(object, object)
    object.ReferenceEquals(object, object)
    object.GetHashCode()
    Namespace: Reportman.Hub.Client.DataChannel
    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
    Type Description
    bool
    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
    Type Description
    bool
    View Source

    Mode

    Declaration
    public ConnectionMode Mode { get; }
    Property Value
    Type Description
    ConnectionMode

    Methods

    View Source

    DisposeAsync()

    Declaration
    public ValueTask DisposeAsync()
    Returns
    Type Description
    ValueTask
    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
    Type Name Description
    string action
    object data
    CancellationToken ct
    Returns
    Type Description
    Task<byte[]>
    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
    Type Name Description
    CancellationToken ct
    Returns
    Type Description
    Task<bool>
    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
    Type Name Description
    HttpClient http
    Uri apiBaseUri
    string bearer
    object startBody
    Action<QueryProgress> onProgress
    CancellationToken ct
    Returns
    Type Description
    Task<WebRtcDataChannelSession>

    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
    Type Description
    Action<string>

    Implements

    IAsyncDisposable
    • View Source
    In this article
    Back to top Generated by DocFX