Totodore/socketioxide

Rustdocs.rs/socketioxide

A socket.io server implementation in Rust that integrates with the Tower ecosystem and the Tokio stack.

hyperrustsocket-iotokioaxumtower
スター成長
スター
1.6k
フォーク
82
週間成長
+0
Issue
12
5001k1.5k
2023年4月2024年5月2025年7月2026年9月
成果物crates.io
README

Socketioxide 🚀🦀

Shows Anuraghazra's GitHub Stats.

A socket.io server implementation in Rust that integrates with the Tower ecosystem and the Tokio stack. It integrates with any server framework based on tower like Axum, Warp, Salvo, Viz or Hyper. Add any other tower based middleware on top of socketioxide such as CORS, authorization, compression, etc with tower-http.

Crates.io Documentation CI

Features

Examples

Chat app 💬 (see full example here)
io.ns("/", |s: SocketRef| {
    s.on("new message", |s: SocketRef, Data::<String>(msg)| {
        let username = s.extensions.get::<Username>().unwrap().clone();
        let msg = Res::Message {
            username,
            message: msg,
        };
        s.broadcast().emit("new message", msg).ok();
    });

    s.on(
        "add user",
        |s: SocketRef, Data::<String>(username), user_cnt: State<UserCnt>| {
            if s.extensions.get::<Username>().is_some() {
                return;
            }
            let num_users = user_cnt.add_user();
            s.extensions.insert(Username(username.clone()));
            s.emit("login", Res::Login { num_users }).ok();

            let res = Res::UserEvent {
                num_users,
                username: Username(username),
            };
            s.broadcast().emit("user joined", res).ok();
        },
    );

    s.on("typing", |s: SocketRef| {
        let username = s.extensions.get::<Username>().unwrap().clone();
        s.broadcast()
            .emit("typing", Res::Username { username })
            .ok();
    });

    s.on("stop typing", |s: SocketRef| {
        let username = s.extensions.get::<Username>().unwrap().clone();
        s.broadcast()
            .emit("stop typing", Res::Username { username })
            .ok();
    });

    s.on_disconnect(|s: SocketRef, user_cnt: State<UserCnt>| {
        if let Some(username) = s.extensions.get::<Username>() {
            let num_users = user_cnt.remove_user();
            let res = Res::UserEvent {
                num_users,
                username: username.clone(),
            };
            s.broadcast().emit("user left", res).ok();
        }
    });
});
Echo implementation with Axum 🏓
use axum::routing::get;
use serde_json::Value;
use socketioxide::{
    extract::{AckSender, Bin, Data, SocketRef},
    SocketIo,
};
use tracing::info;
use tracing_subscriber::FmtSubscriber;

fn on_connect(socket: SocketRef, Data(data): Data<Value>) {
    info!("Socket.IO connected: {:?} {:?}", socket.ns(), socket.id);
    socket.emit("auth", data).ok();

    socket.on(
        "message",
        |socket: SocketRef, Data::<Value>(data), Bin(bin)| {
            info!("Received event: {:?} {:?}", data, bin);
            socket.bin(bin).emit("message-back", data).ok();
        },
    );

    socket.on(
        "message-with-ack",
        |Data::<Value>(data), ack: AckSender, Bin(bin)| {
            info!("Received event: {:?} {:?}", data, bin);
            ack.bin(bin).send(data).ok();
        },
    );
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    tracing::subscriber::set_global_default(FmtSubscriber::default())?;

    let (layer, io) = SocketIo::new_layer();

    io.ns("/", on_connect);
    io.ns("/custom", on_connect);

    let app = axum::Router::new()
        .route("/", get(|| async { "Hello, World!" }))
        .layer(layer);

    info!("Starting server");

    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
    axum::serve(listener, app).await.unwrap();

    Ok(())
}
Other examples are available in the example folder

Contributions and Feedback / Questions

Any contribution is welcome, feel free to open an issue or a PR. If you want to contribute but don't know where to start, you can check the issues.

If you have any question or feedback, please open a thread on the discussions page.

License 🔐

This project is licensed under the MIT license.

関連リポジトリ
vercel/hyper

A terminal built on web technologies

TypeScriptnpmcliMIT Licenseterminaljavascript
hyper.is
44.7k3.6k
hyperium/hyper

An HTTP library for Rust

Rustcrates.iolibraryMIT Licenserusthyper
hyper.rs
16.3k1.8k
bnb/awesome-hyper

🖥 Delightful Hyper plugins, themes, and resources

awesomeCreative Commons Zero v1.0 Universalhyperhyperterm
11k372
xonsh/xonsh

🐚 Python-powered shell. Full-featured, cross-platform and AI-friendly.

PythonPyPIOtherxonshdevops
xon.sh
9.6k740
enquirer/enquirer

Stylish, intuitive and user-friendly prompts. Used by eslint, webpack, yarn, pm2, pnpm, RedwoodJS, FactorJS, salesforce, Cypress, Google Lighthouse, Generate, tencent cloudbase, lint-staged, gluegun, hygen, hardhat, AWS Amplify, GitHub Actions Toolkit, @airbnb/nimbus, and more! Please follow Enquirer's author: https://github.com/jonschlinkert

JavaScriptnpmcliMIT Licensepromptinquirer
github.com/jonschlinkert
8k295
mjswensen/themer

🎨 themer takes a set of colors and outputs themes for your apps (editors, terminals, wallpapers, and more).

TypeScriptnpmcliMIT Licensewallpapersthemer
themer.dev
5.9k137
daltonmenezes/aura-theme

✨ A beautiful dark theme for your favorite apps.

TypeScriptnpmcliMIT Licensevscodetheme
3.8k185
AutomatedLab/AutomatedLab

AutomatedLab is a provisioning solution and framework that lets you deploy complex labs on HyperV and Azure with simple PowerShell scripts. It supports all Windows operating systems from 2008 R2 to 2022, some Linux distributions and various products like AD, Exchange, PKI, IIS, etc.

PowerShellMIT Licensepowershelldeployment
2.2k384
sindresorhus/hyper-snazzy

Elegant Hyper theme with bright colors

JavaScriptnpmcliMIT Licensehyperhyper-theme
1.5k72
klaudiosinani/hyper-pokemon

Tailor-made Pokémon themes for your Hyper terminal

JavaScriptnpmMIT Licensepokemonhyper
klaudiosinani.com/hyper-pokemon
1.2k73
onmyway133/FinderGo

🐢 Open terminal quickly from Finder

SwiftcliOtherfindersync
onmyway133.com
1.2k70