Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Session

A live WebSocket session that hosts multiple concurrent subscriptions over a single connection.

Setup

A Session is produced by WsClient::connect; it has no public constructor.

use {
    anyhow::Result,
    dango_sdk::{Session, WsClient},
};
 
#[tokio::main]
async fn main() -> Result<()> {
    let session: Session = WsClient::new("wss://api-mainnet.dango.zone/graphql")?
        .connect()
        .await?;
    let _ = session;
    Ok(())
}
pub struct Session {
    inner: Arc<SessionInner>,
}

Session is Debug + Clone. Cloning shares the same underlying connection and command channel.

Configuration

Session has no configuration surface. The keepalive interval and protocol are fixed at construction time.

Methods

MethodDescription
subscribeMultiplex a new GraphQL subscription onto the existing connection.

End-to-end example

use {
    anyhow::Result,
    dango_sdk::{SubscribeBlock, SubscribeTrades, WsClient, subscribe_block, subscribe_trades},
    futures::StreamExt,
};
 
#[tokio::main]
async fn main() -> Result<()> {
    let session = WsClient::new("wss://api-mainnet.dango.zone/graphql")?
        .connect()
        .await?;
 
    let mut blocks = session
        .subscribe::<SubscribeBlock>(subscribe_block::Variables {})
        .await?;
    let mut trades = session
        .subscribe::<SubscribeTrades>(subscribe_trades::Variables {
            base_denom:  "dango".into(),
            quote_denom: "bridge/usdc".into(),
        })
        .await?;
 
    loop {
        tokio::select! {
            Some(item) = blocks.next() => println!("block: {item:?}"),
            Some(item) = trades.next() => println!("trade: {item:?}"),
            else => break,
        }
    }
 
    // Both streams and `session` drop here; the connection is closed.
    Ok(())
}

Lifecycle

Session is backed by an Arc. The connection stays open as long as:

  • at least one Session clone is alive, or
  • at least one SubscriptionStream derived from this session is alive.

When the last Session clone drops, the inner Drop impl sends a Close command to the background driver task; remaining streams keep working until the server closes the connection or the stream itself is dropped. When the last stream then drops, the connection closes cleanly.

Individual stream drops send a complete to the server for that subscription id, freeing the slot in the 30-per-connection cap.

Notes

  • The first nine bits of every subscription id are generated from an internal AtomicU64 per session. Ids are local to one Session — they do not collide across sessions.
  • Subscription order on the wire is the order of subscribe calls. The server may reply out of order.
  • Session::subscribe returns Err only if the command channel to the driver task is closed (i.e. the session is dead).

See also