Socket.IO server implementation as a tower layer in Rust
It integrates with any framework based on tower/hyper, such as:
It takes full advantage of the tower and tower-http ecosystem of middleware, services, and utilities.
⚠️ This crate is under active development and the API is not yet stable.
- Namespaces
- Rooms
- Handshake data
- Ack and emit with ack
- Binary
- Polling & Websocket transport
- Extensions on socket to add custom data to sockets
- Other adapter to share state between server instances (like redis adapter), currently only the in memory adapter is implemented
- State recovery when a socket reconnects
- SocketIo v3 support (currently only v4 is supported)
- Chat app with Axum
- Echo implementation with Axum :
use axum::routing::get;
use axum::Server;
use serde::{Serialize, Deserialize};
use socketioxide::{Namespace, SocketIoLayer};
use serde_json::Value;
#[derive(Debug, Serialize, Deserialize)]
struct MyData {
pub name: String,
pub age: u8,
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("Starting server");
let ns = Namespace::builder()
.add("/", |socket| async move {
println!("Socket connected on / namespace with id: {}", socket.sid);
// Add a callback triggered when the socket receive an 'abc' event
// The json data will be deserialized to MyData
socket.on("abc", |socket, data: MyData, bin, _| async move {
println!("Received abc event: {:?} {:?}", data, bin);
socket.bin(bin).emit("abc", data).ok();
});
// Add a callback triggered when the socket receive an 'acb' event
// Ackknowledge the message with the ack callback
socket.on("acb", |_, data: Value, bin, ack| async move {
println!("Received acb event: {:?} {:?}", data, bin);
ack.bin(bin).send(data).ok();
});
})
.add("/custom", |socket| async move {
println!("Socket connected on /custom namespace with id: {}", socket.sid);
})
.build();
let app = axum::Router::new()
.route("/", get(|| async { "Hello, World!" }))
.layer(SocketIoLayer::new(ns));
Server::bind(&"127.0.0.1:3000".parse().unwrap())
.serve(app.into_make_service())
.await?;
Ok(())
}