#async-io #web #io

mews

Minimal and Efficient, Multi-Environment WebSocket implementation for async Rust

11 unstable releases (4 breaking)

0.5.2 Sep 8, 2025
0.5.1 Sep 2, 2025
0.4.2 Aug 14, 2025
0.3.0 Aug 11, 2025
0.1.1 Oct 31, 2024

#56 in WebSocket

Download history 228/week @ 2025-08-18 543/week @ 2025-08-25 446/week @ 2025-09-01 376/week @ 2025-09-08 229/week @ 2025-09-15 123/week @ 2025-09-22 272/week @ 2025-09-29 246/week @ 2025-10-06 209/week @ 2025-10-13 196/week @ 2025-10-20 86/week @ 2025-10-27 50/week @ 2025-11-03 54/week @ 2025-11-10 49/week @ 2025-11-17 48/week @ 2025-11-24 194/week @ 2025-12-01

350 downloads per month
Used in ohkami

MIT license

49KB
853 lines

MEWS

Minimal and Efficient, Multi-Environment WebSocket implementation for async Rust

License CI status crates.io

Features

  • Minimal and Efficient : minimal codebase to provide efficient, memory-safe WebSocket handling.

  • Multi-Environment : works with any async runtimes with tokio::io or futures::io interface (for example: tokio or nio use tokio::io interface, and smol or glommio use futures::io interface).
    Feature flags io_tokio or io_futures enables integration for respective IO interface.

Usage

io_tokio or io_futures must be activated to integrate with async IO interfaces.

Here specifying io_tokio to use with tokio:

[dependencies]
mews  = { version = "0.5", features = ["io_tokio"] }
tokio = { version = "1", features = ["full"] }
# ...

( with pseudo Request & Response )

/* server */

use tokio::net::TcpStream;
use mews::{WebSocketContext, Connection, Message};

async fn handle_websocket(
    req: &Request/* upgrade request */,
    tcp: TcpStream
) {
    let ctx = WebSocketContext::new(
        &req.headers["Sec-WebSocket-Key"]
    );

    let (sign, ws) = ctx.on_upgrade(
        |mut conn: Connection<TcpStream>| async move {
            while let Ok(Some(Message::Text(text))) = conn.recv().await {
                conn.send(text).await
                    .expect("failed to send message");
                sleep(Duration::from_secs(1)).await;
            }
        }
    );

    send(Response::SwitchingProtocol()
        .with(Connection, "Upgrade")
        .with(Upgrade, "websocket")
        .with(SecWebSocketAccept, sign),
        &mut tcp
    ).await.expect("failed to send handshake response");

    ws.manage(tcp);
}
/* client */

use tokio::net::TcpStream;

async fn start_websocket(
    mut tcp: TcpStream
) {
    let websocket_key = "my-sec-websocket-key";

    let ctx = WebSocketContext::new(
        websocket_key
    );

    let (sign, ws) = ctx.on_upgrade(
        |mut conn: Connection<TcpStream>| async move {
            conn.send("Hello!").await.expect("failed to send message");
            while let Ok(Some(Message::Text(text))) = conn.recv().await {
                println!("got: `{text}`")
            }
        }
    );

    let res = send(Request::GET("/ws")
        .with(Host, "localhost:3000")
        .with(Connection, Upgrade)
        .with(Upgrade, "websocket")
        .with(SecWebSocketVersion, "13")
        .with(SecWebSocketKey, websocket_key),
        &mut tcp
    ).await.expect("failed to send handshake request");

    assert!(res.header(SecWebSocketAccept), Some(sign));

    ws.manage(tcp);
}

License

MEWS is licensed under MIT LICENSE ( LICENSE or https://opensource.org/licenses/MIT ).

Dependencies

~0.8–4MB
~80K SLoC