DEV Community

Cover image for ⚡Socketioxide - SocketIO server powered by Rust! 🦀
Tausif
Tausif

Posted on • Edited on

⚡Socketioxide - SocketIO server powered by Rust! 🦀

Rust is hard, so is writing networking code in it. But who doesn’t want its blazing fast speed? Socketioxide fills the gap. It’s socket.io, but with speed and safety, that helps you achieve unimaginable while keeping it dead simple.

Socket.io is a massively popular websocket/polling framework with about 60k stars on github. Socket.io server is officially written in Node.js, which was ported to Python, Go (upto v1.4), Java and Swift by the community. Now, there is a Rust port as well, Socketioxide:

GitHub logo Totodore / socketioxide

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

Socketioxide 🚀🦀

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.

⚠️ This crate is under active development and the API is not yet stable.

Crates.io Documentation CI

Features :

🎉 Latest Release (v0.8.0)

v0.8.0 was released on Dec 12. See the full release note here: https://github.com/Totodore/socketioxide/releases/tag/v0.8.0

💎 Socketioxide Features

  1. Integrates with:
  2. Out of the box support for any other middleware based on tower :
  3. Namespaces
  4. Rooms
  5. Ack and emit with ack
  6. Binary packets
  7. Polling & Websocket transports
  8. Extensions to add custom data to sockets
  9. Memory efficient http payload parsing with streams
  10. Api that mimics the socket.io JavaScript api as much as possible
  11. Well tested with the official end to end test-suite
  12. Socket.io versions supported :
    • protocol v5 : based on engine.io v4 under the feature flag v5 (default), (socket.io js from v3.0.0..latest)
    • protocol v4 : based on engine.io v3, feature flag v4, (socket.io js from v1.0.3..latest)

🪄 Power of Rust + Simplicity of Socket IO

The thing about socket.io is that it’s so simple, that someone who just learned JavaScript can get started with it. Write an html page, bring the client and hook some event listeners.

On the other hand, Rust is a language with powerful type system and runtime speed. Programs written in Rust are more memory safe than C, C++ etc. That makes Rust a great choice for both mission critical and general purpose software development.

Now that you can combine the simplicity and power together, Socketioxide emerges as a great choice for realtime apps.

🧑‍💻 How to get started with it?

This is an example of socket.io echo server with Socketioxide and Axum

use axum::routing::get;
use axum::Server;
use serde_json::Value;
use socketioxide::SocketIo;
use tracing::info;
use tracing_subscriber::FmtSubscriber;

#[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("/", |socket, auth: Value| async move {
        info!("Socket.IO connected: {:?} {:?}", socket.ns(), socket.sid);
        socket.emit("auth", auth).ok();

        socket.on("message", |socket, data: Value, bin, _| async move {
            info!("Received event: {:?} {:?}", data, bin);
            socket.bin(bin).emit("message-back", data).ok();
        });

        socket.on("message-with-ack", |_, data: Value, bin, ack| async move {
            info!("Received event: {:?} {:?}", data, bin);
            ack.bin(bin).send(data).ok();
        });

        socket.on_disconnect(|socket, reason| async move {
            info!("Socket.IO disconnected: {} {}", socket.sid, reason);
        });
    });

    io.ns("/custom", |socket, auth: Value| async move {
        info!("Socket.IO connected on: {:?} {:?}", socket.ns(), socket.sid);
        socket.emit("auth", auth).ok();
    });

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

    info!("Starting server");

    Server::bind(&"127.0.0.1:3000".parse().unwrap())
        .serve(app.into_make_service())
        .await?;

    Ok(())
}
Enter fullscreen mode Exit fullscreen mode

If you want to build a chat app, here is an example to get you started: https://github.com/Totodore/socketioxide/tree/main/examples/src/chat

If you are planning to use a frontend framework like React, Angular or Svelte, consult the official docs: https://socket.io/docs/v3/client-initialization/

Try it out and star⭐ on Github!

Top comments (1)

Collapse
 
psionyc profile image
Ione Ione

Hmm... Nice