12 个版本

0.3.3 2024年1月9日
0.3.2 2023年12月26日
0.3.0 2023年5月11日
0.2.1 2020年11月11日
0.0.1 2020年10月14日

#180 in 异步

Download history 1/week @ 2024-04-13 9/week @ 2024-04-20 5/week @ 2024-04-27 17/week @ 2024-05-04 4/week @ 2024-05-18 2/week @ 2024-05-25 4/week @ 2024-06-01 3/week @ 2024-06-08 2/week @ 2024-06-29 27/week @ 2024-07-20 45/week @ 2024-07-27

74 每月下载量

MIT 许可证

48KB
1K SLoC

async-smux

crates.io

为 smol/async-std 和任何与 futures 兼容的异步运行时提供轻量级的异步 smux (Simple MUltipleXing) 库。

img

async-smux 消费一个实现 AsyncRead + AsyncWrite + Unpin + Send 的结构体,例如 TcpStreamTlsStream,以创建一个 Mux<T> 结构体。然后您可以在 Mux<T> 上创建多个 MuxStream<T>(最多 4294967295 个),这也实现了 AsyncRead + AsyncWrite + Unpin + Send

基准测试

以下是我本地机器上的简单基准测试结果,与原始版本 smux(用 go 编写)进行比较。

实现 吞吐量(TCP) 握手
smux (go) 0.4854 GiB/s 17.070 K/s
async-smux (rust) 1.0550 GiB/s 81.774 K/s

运行 cargo bench 以自行测试。有关更多详细信息,请检查 /benches 目录。

惰性

此库不会生成任何线程或任务。它只生成一些 future。因此,它与运行时完全独立。

MuxMuxStream 完全是惰性的,如果您不调用 poll(),它们将不会执行任何操作。

任何轮询操作,包括 .read().write()accept()connect(),都将使 MuxMuxStream 运行。

规范

VERSION(1B) | CMD(1B) | LENGTH(2B) | STREAMID(4B) | DATA(LENGTH)

VERSION: 1

CMD:
    SYN(0)
    FIN(1)
    PSH(2)
    NOP(3)

STREAMID: Randomly chosen number

示例

use async_smux::{Mux, MuxConfig};
use async_std::net::{TcpListener, TcpStream};
use async_std::prelude::*;

async fn echo_server() {
    let listener = TcpListener::bind("0.0.0.0:12345").await.unwrap();
    let (stream, _) = listener.accept().await.unwrap();
    let mux = Mux::new(stream, MuxConfig::default());
    loop {
        let mut mux_stream = mux.accept().await.unwrap();
        let mut buf = [0u8; 1024];
        let size = mux_stream.read(&mut buf).await.unwrap();
        mux_stream.write(&buf[..size]).await.unwrap();
    }
}

fn main() {
    async_std::task::spawn(echo_server());
    async_std::task::block_on(async {
        smol::Timer::after(std::time::Duration::from_secs(1)).await;
        let stream = TcpStream::connect("127.0.0.1:12345").await.unwrap();
        let mux = Mux::new(stream, MuxConfig::default());
        for i in 0..100 {
            let mut mux_stream = mux.connect().await.unwrap();
            let mut buf = [0u8; 1024];
            mux_stream.write(b"hello").await.unwrap();
            let size = mux_stream.read(&mut buf).await.unwrap();
            let reply = String::from_utf8(buf[..size].to_vec()).unwrap();
            println!("{}: {}", i, reply);
        }
    });
}

依赖

~4–11MB
~104K SLoC