websockets-monoio

Crates.iowebsockets-monoio
lib.rswebsockets-monoio
version0.1.1
created_at2025-10-23 14:41:35.899071+00
updated_at2025-10-23 16:58:22.968498+00
descriptionMonoio (io_uring) WebSocket client built on fastwebsockets_monoio with wss support.
homepagehttps://github.com/ChetanBhasin/websockets-monoio
repositoryhttps://github.com/ChetanBhasin/websockets-monoio
max_upload_size
id1897207
size117,159
Chetan Bhasin (ChetanBhasin)

documentation

https://docs.rs/websockets-monoio

README

websockets-monoio

Crates.io lib.rs Documentation License Downloads

A high-performance WebSocket client for the monoio async runtime. It dials both ws:// and wss:// endpoints, performs the HTTP upgrade handshake, and hands you a fully configured [fastwebsockets_monoio::WebSocket] client stream.

Note: Documentation is AI generated.

Highlights

  • Monoio-first: Uses io_uring on Linux via monoio for low-latency networking.
  • TLS out of the box: wss:// connections use monoio-rustls with the Mozilla root store.
  • Zero-copy friendly: Frame writes avoid intermediate allocations whenever possible.
  • Safe defaults: Auto close and auto pong are enabled; TLS writev is disabled for compatibility.
  • Minimal surface area: One WsClient::connect helper plus re-exported stream types if you want lower-level control.

Install

Add the crate and its companion dependencies to your project:

[dependencies]
websockets-monoio = "0.1.1"
monoio = "0.2"
fastwebsockets-monoio = "0.10"
anyhow = "1.0"

The crate targets Rust 1.90.0 or newer (see Cargo.toml).

Usage

Basic WebSocket connection

use fastwebsockets_monoio::{Frame, OpCode};
use websockets_monoio::WsClient;

#[monoio::main]
async fn main() -> anyhow::Result<()> {
    let mut client = WsClient::connect("wss://echo.websocket.org/", &[]).await?;

    client
        .ws
        .write_frame(Frame::text("Hello, WebSocket!".as_bytes().into()))
        .await?;

    let frame = client.ws.read_frame().await?;
    if let OpCode::Text = frame.opcode {
        println!("Received: {}", std::str::from_utf8(&frame.payload)?);
    }

    Ok(())
}

Streaming example

use fastwebsockets_monoio::{Frame, OpCode};
use websockets_monoio::WsClient;

#[monoio::main]
async fn main() -> anyhow::Result<()> {
    let mut client =
        WsClient::connect("wss://stream.binance.com:9443/ws/btcusdt@trade", &[]).await?;

    let subscribe = r#"{"method":"SUBSCRIBE","params":["btcusdt@trade"],"id":1}"#;
    client
        .ws
        .write_frame(Frame::text(subscribe.as_bytes().into()))
        .await?;

    loop {
        let frame = client.ws.read_frame().await?;
        match frame.opcode {
            OpCode::Text => println!("{}", std::str::from_utf8(&frame.payload)?),
            OpCode::Binary => println!("Binary frame ({} bytes)", frame.payload.len()),
            OpCode::Close => break,
            _ => {}
        }
    }

    Ok(())
}

Custom request headers

use websockets_monoio::WsClient;

#[monoio::main]
async fn main() -> anyhow::Result<()> {
    let client = WsClient::connect(
        "wss://api.example.com/socket",
        &[
            ("Authorization", "Bearer your-token"),
            ("User-Agent", "your-app/1.0"),
        ],
    )
    .await?;

    // Use client.ws ...
    drop(client);
    Ok(())
}

Further examples live in examples/:

  • cargo run --example echo_client
  • cargo run --example crypto_stream

API overview

  • WsClient::connect(url, extra_headers) performs DNS resolution, TCP/TLS setup, and the HTTP upgrade handshake before returning a WebSocket<WsStream>.
  • WsClient::into_inner() gives direct access to the underlying fastwebsockets_monoio::WebSocket.
  • WsStream is the enum used by the client (Plain TCP or Tls over TCP). It implements monoio_compat::AsyncRead and AsyncWrite.
  • Supporting modules such as http_upgrade, tls, and url are re-exported for advanced use-cases if you want to build your own handshake flow.

Errors from WsClient::connect use anyhow::Result, allowing full context while still being compatible with other error handling strategies.

Benchmarks

Benchmarks live in benches/perf.rs and run locally without external services. Launch them with:

cargo bench

What you get:

  • connect/ws_connect measures full handshake latency against an in-process monoio echo server.
  • round_trip/* tests send-and-receive latency for text and binary frames of varying sizes.

Results depend on kernel support for io_uring; Linux 5.1+ is recommended for representative numbers.

Platform notes

  • Linux: Full support with io_uring. This is the primary target.
  • macOS / Windows: Works via monoio’s fallback driver, but without io_uring optimisations.

TLS connections use rustls with the Mozilla CA bundle (webpki-roots). A global TlsConnector is reused across calls to keep setup cheap.

Contributing

Issues and PRs are welcome. By contributing you agree to license your work under MIT OR Apache-2.0, the same as the rest of the project.

License

Licensed under either of:

at your option.

Commit count: 0

cargo fmt