Skip to main content

WebsocketHandle

Struct WebsocketHandle 

Source
pub struct WebsocketHandle { /* private fields */ }
Expand description

Handle to an active WebSocket connection.

Provides methods to send messages and receive responses.

§Thread Safety

WebsocketHandle is Send but not Sync. The underlying WebSocket transport contains non-thread-safe internal buffers.

If you need to share the handle across async tasks, wrap it in a tokio::sync::Mutex:

use std::sync::Arc;
use tokio::sync::Mutex;

let ws = Arc::new(Mutex::new(client.connect_ws().call().await?));

// Receiving task
let ws_recv = ws.clone();
tokio::spawn(async move {
    loop {
        let msg = ws_recv.lock().await.recv().await;
        // handle msg ...
    }
});

// Sending task
ws.lock().await.subscribe([Topic::agg_trade("BTC-USD")], None).await?;

For high-throughput bots, a common pattern is to dedicate one task to the WebSocket and use tokio::sync::mpsc channels to communicate with other tasks — this avoids lock contention on the hot path.

§Extracting the Inner Socket

If you need direct access to the underlying reqwest_websocket::WebSocket, use the Deref implementation.

Implementations§

Source§

impl WebsocketHandle

Source

pub async fn send(&mut self, msg: ClientMessage) -> SDKResult<(), WSErrors>

Send a message to the server.

§Available Message Types
  • ClientMessage::Subscribe - Subscribe to market data streams
  • ClientMessage::Unsubscribe - Unsubscribe from streams
  • ClientMessage::ListSubscriptions - List active subscriptions
  • ClientMessage::Ping - Manual ping (not needed for keepalive)
  • ClientMessage::OrderPlace - Place an order
  • ClientMessage::OrderCancel - Cancel an order
§Example
use bullet_rust_sdk::types::ClientMessage;

// Subscribe to aggregated trades
ws.send(ClientMessage::Subscribe {
    id: Some(1.into()),
    params: vec!["BTC-USD@aggTrade".to_string()],
})
.await?;

// Unsubscribe later
ws.send(ClientMessage::Unsubscribe {
    id: Some(2.into()),
    params: vec!["BTC-USD@aggTrade".to_string()],
})
.await?;
Source

pub async fn recv(&mut self) -> SDKResult<ServerMessage, WSErrors>

Receive the next message from the server.

§Errors
§Parse Errors

If a message cannot be parsed into a known ServerMessage variant, it returns ServerMessage::Unknown(error, raw_text) instead of failing. This allows you to log or debug unexpected message formats.

§Example
use bullet_rust_sdk::errors::WSErrors;
use bullet_rust_sdk::types::ClientMessage;
use bullet_rust_sdk::ws::models::{ServerMessage, TaggedMessage};

let api = Client::mainnet().await?;

'reconnect: loop {
    let mut ws = api.connect_ws().call().await?;

    ws.send(ClientMessage::Subscribe {
        id: Some(1.into()),
        params: vec!["BTC-USD@aggTrade".to_string()],
    })
    .await?;

    loop {
        match ws.recv().await {
            Ok(msg) => match msg {
                ServerMessage::AggTrade(trade) => {
                    println!("Trade: {} @ {}", trade.symbol, trade.price);
                }
                ServerMessage::Tagged(TaggedMessage::Pong(_)) => {}
                ServerMessage::Tagged(TaggedMessage::Error(err)) => {
                    eprintln!("Server error: {:?}", err);
                }
                _ => {}
            },
            Err(WSErrors::WsClosed { code, reason }) => {
                eprintln!("Connection closed (code {:?}): {}", code, reason);
                continue 'reconnect;
            }
            Err(WSErrors::WsStreamEnded) => {
                eprintln!("Connection lost unexpectedly");
                continue 'reconnect;
            }
            Err(e) => return Err(e.into()),
        }
    }
}
Source

pub async fn subscribe( &mut self, topics: impl IntoIterator<Item = Topic>, id: Option<RequestId>, ) -> SDKResult<(), WSErrors>

Subscribe to one or more topics.

§Arguments
  • topics - Topics to subscribe to
  • id - Optional request ID for matching the server’s response
§Example
use bullet_rust_sdk::types::RequestId;
use bullet_rust_sdk::{Client, OrderbookDepth, Topic};

let api = Client::mainnet().await?;
let mut ws = api.connect_ws().call().await?;

// Subscribe to multiple topics using type-safe builders
ws.subscribe(
    [
        Topic::agg_trade("BTC-USD"),
        Topic::depth("ETH-USD", OrderbookDepth::D10),
        Topic::book_ticker("SOL-USD"),
    ],
    Some(RequestId::new(1)),
)
.await?;

// Now receive market data
loop {
    let msg = ws.recv().await?;
    println!("{:?}", msg);
}
Source

pub async fn list_subscriptions( &mut self, id: Option<RequestId>, ) -> SDKResult<(), WSErrors>

Unsubscribe from one or more topics.

Unsubscribe is idempotent - unsubscribing from topics you’re not subscribed to will still succeed.

§Arguments
  • topics - Topics to unsubscribe from
  • id - Optional request ID for matching the server’s response
§Example
use bullet_rust_sdk::Client;
use bullet_rust_sdk::types::RequestId;

let api = Client::mainnet().await?;
let mut ws = api.connect_ws().call().await?;

ws.list_subscriptions(Some(RequestId::new(1))).await?;
// Match response by request_id
Source

pub async fn order_place( &mut self, tx: impl Into<String>, id: Option<RequestId>, ) -> SDKResult<(), WSErrors>

Place an order via WebSocket.

§Arguments
  • tx - Base64-encoded raw transaction bytes
  • id - Optional request ID for matching the server’s response
§Example
use bullet_rust_sdk::Client;
use bullet_rust_sdk::types::RequestId;

let api = Client::mainnet().await?;
let mut ws = api.connect_ws().call().await?;

let tx_bytes = "base64_encoded_transaction";
ws.order_place(tx_bytes, Some(RequestId::new(1))).await?;
// Match response by request_id
Source

pub async fn order_cancel( &mut self, tx: impl Into<String>, id: Option<RequestId>, ) -> SDKResult<(), WSErrors>

Cancel an order via WebSocket.

§Arguments
  • tx - Base64-encoded raw transaction bytes
  • id - Optional request ID for matching the server’s response
§Example
use bullet_rust_sdk::Client;
use bullet_rust_sdk::types::RequestId;

let api = Client::mainnet().await?;
let mut ws = api.connect_ws().call().await?;

let tx_bytes = "base64_encoded_cancel_transaction";
ws.order_cancel(tx_bytes, Some(RequestId::new(1))).await?;
// Match response by request_id
Source

pub async fn place_order( &mut self, signed: &Transaction, id: Option<RequestId>, ) -> SDKResult<(), WSErrors>

Place an order via WebSocket using a signed transaction.

This is a convenience wrapper around order_place that handles base64 encoding internally.

§Example
use bullet_rust_sdk::{Client, Transaction};

let signed = Transaction::builder()
    .call_message(call_msg)
    .client(&client)
    .build()?;

ws.place_order(&signed, None).await?;
Source

pub async fn cancel_order( &mut self, signed: &Transaction, id: Option<RequestId>, ) -> SDKResult<(), WSErrors>

Cancel an order via WebSocket using a signed transaction.

This is a convenience wrapper around order_cancel that handles base64 encoding internally.

§Example
use bullet_rust_sdk::{Client, Transaction};

let signed = Transaction::builder()
    .call_message(cancel_msg)
    .client(&client)
    .build()?;

ws.cancel_order(&signed, None).await?;

Methods from Deref<Target = WebSocket>§

Source

pub fn protocol(&self) -> Option<&str>

Returns the protocol negotiated during the handshake.

Trait Implementations§

Source§

impl Deref for WebsocketHandle

Source§

type Target = WebSocket

The resulting type after dereferencing.
Source§

fn deref(&self) -> &Self::Target

Dereferences the value.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more