Skip to main content

Crate sioc

Crate sioc 

Source
Expand description

§sioc

Typed, ergonomic Socket.IO protocol v5 client for Rust.

§What is Socket.IO?

The Socket.IO protocol v5 is a real-time, bidirectional event-based communication protocol built on top of the Engine.IO protocol v4.

It adds features such as namespaces, which allow multiple channels over a single connection; events, which are named messages with structured data; acknowledgements, enabling request/response patterns over events; and support for binary attachments.

§Features

  • Supports Socket.IO protocol v5 and Engine.IO protocol v4.
  • Async networking built on Tokio, reqwest, and tokio-tungstenite.
  • No boxed futures and a lock-free actor model. Channel-based event loops avoid callback borrow issues and fit stateful applications naturally.
  • Derive macros for events, acks, serialization, and routing.
  • Zero-copy packet parsing via bytestring and bytes.

§Quick start

This example requires a running Socket.IO server. See the quick-start example for a self-contained demo.

use sioc::prelude::*;
use std::time::Duration;
use url::Url;

#[derive(Debug, EventType, DeserializePayload)]
#[sioc(event(name = "greeting"))]
struct Greeting {
    message: String,
}

#[derive(Debug, EventType, SerializePayload)]
#[sioc(event(name = "reply"))]
struct Reply {
    text: String,
}

#[derive(Debug, EventType, DeserializePayload)]
#[sioc(event(name = "poll", ack = "Vote"))]
struct Survey {
    question: String,
    options: Vec<String>,
}

#[derive(Debug, AckType, SerializePayload)]
struct Vote(usize);

#[derive(Debug, EventType, SerializePayload)]
#[sioc(event(name = "join", ack = "RoomInfo"))]
struct Join {
    room: String,
}

#[derive(Debug, AckType, DeserializePayload)]
struct RoomInfo {
    count: u32,
}

#[derive(Debug, EventRouter)]
enum AppEvent {
    Greeting(Event<Greeting>),
    Survey(Event<Survey>),
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let url = Url::parse("http://localhost:3000")?;

    let client = ClientBuilder::new(url).open()?;
    let (tx, mut rx) = client.connect("/").await?;

    let Ack { payload: RoomInfo { count }, .. } = tx
        .emit(Join { room: "lobby".into() })
        .await?
        .timeout(Duration::from_secs(5))
        .await?;

    println!("joined lobby with {count} members");

    while let Some(event) = rx.listen::<AppEvent>().await? {
        match event {
            AppEvent::Greeting(Event { payload: Greeting { message }, .. }) => {
                println!("greeting: {message}");
                tx.emit(Reply { text: "glad to be here!".into() }).await?;
            }

            AppEvent::Survey(Event { payload: Survey { question, options }, id, .. }) => {
                println!("poll: {question} ({} options)", options.len());
                tx.acknowledge(id, Vote(0)).await?;
            }
        }
    }

    tx.disconnect().await?;

    client.join().await?;

    Ok(())
}

§License

Licensed under MIT OR Apache-2.0.

Modules§

ack
Typed Socket.IO acknowledgements (request/response over events).
binary
Binary attachment support for Socket.IO events and acknowledgements.
client
Socket.IO client and namespace handles.
config
error
Error types for the sioc crate.
event
Typed Socket.IO events: the primary way to send and receive data.
manager
Socket.IO namespace router.
marker
Compile-time markers that encode whether a packet carries binary attachments and/or expects an acknowledgement.
packet
Socket.IO v4 packet types and wire encoding.
payload
prelude