A lightweight asynchronous smux (Simple MUltipleXing) library for smol/async-std and any async runtime compatible to futures
.
async-smux consumes a struct implementing AsyncRead + AsyncWrite + Unpin + Send
, like TcpStream and TlsStream. And then you may spawn multiple MuxStream
s(up to 65535), which also implements AsyncRead + AsyncWrite + Unpin + Send
.
Here is a simple benchmarking result on my local machine, comparing to the original version smux (written in go).
| Implementation | Throughput (TCP) | Handshake | | ----------------- | ---------------- | ---------- | | smux (go) | 0.4854 GiB/s | 17.070 K/s | | async-smux (rust) | 1.0550 GiB/s | 81.774 K/s |
Run cargo bench
to test it by yourself. Check out /benches
directory for more details.
No thread or task will be spawned by this library. It just spawns a few future
s. So it's runtime-independent.
Mux
and MuxStream
are completely lazy and will DO NOTHING if you don't poll()
them.
Any polling operation, including .read()
,.write()
, accept()
and connect()
, will push Mux
and MuxStream
working.
```rust use asyncsmux::{Mux, MuxConfig}; use asyncstd::net::{TcpListener, TcpStream}; use async_std::prelude::*;
async fn echoserver() { 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 muxstream = mux.accept().await.unwrap(); let mut buf = [0u8; 1024]; let size = muxstream.read(&mut buf).await.unwrap(); muxstream.write(&buf[..size]).await.unwrap(); } }
fn main() { asyncstd::task::spawn(echoserver()); asyncstd::task::blockon(async { smol::Timer::after(std::time::Duration::fromsecs(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 muxstream = mux.connect().await.unwrap(); let mut buf = [0u8; 1024]; muxstream.write(b"hello").await.unwrap(); let size = muxstream.read(&mut buf).await.unwrap(); let reply = String::fromutf8(buf[..size].tovec()).unwrap(); println!("{}: {}", i, reply); } }); } ```