A fast RFC6455 WebSocket implementation
fastwebsockets is a fast WebSocket protocol implementation.
Passes the Autobahn|TestSuite1 and fuzzed with LLVM's libfuzzer.
You can use it as a raw websocket frame parser and deal with spec compliance yourself, or you can use it as a full-fledged websocket client/server.
use fastwebsockets::{Frame, OpCode, WebSocket};
async fn handle_client(
mut socket: TcpStream,
) -> Result {
handshake(&mut socket).await?;
let mut ws = WebSocket::after_handshake(socket);
ws.set_writev(true);
ws.set_auto_close(true);
ws.set_auto_pong(true);
loop {
let frame = ws.read_frame().await?;
match frame {
OpCode::Close => break,
OpCode::Text | OpCode::Binary => {
let frame = Frame::new(true, frame.opcode, None, frame.payload);
ws.write_frame(frame).await?;
}
}
}
Ok(())
}
Fragmentation
By default, fastwebsockets will give the application raw frames with FIN set. Other crates like tungstenite which will give you a single message with all the frames concatenated.
For concanated frames, use FragmentCollector:
let mut ws = WebSocket::after_handshake(socket);
let mut ws = FragmentCollector::new(ws);
let incoming = ws.read_frame().await?;
// Always returns full messages
assert!(incoming.fin);
permessage-deflate is not supported yet.
HTTP Upgrade
Enable the upgrade feature to do server-side upgrades and client-side
handshakes.
This feature is powered by hyper.
use fastwebsockets::upgrade;
use hyper::{Request, body::{Incoming, Bytes}, Response};
use http_body_util::Empty;
use anyhow::Result;
async fn server_upgrade(
mut req: Request,
) -> Result> {
let (response, fut) = upgrade::upgrade(&mut req)?;
tokio::spawn(async move {
if let Err(e) = handle_client(fut).await {
eprintln!("Error in websocket connection: {}", e);
}
});
Ok(response)
}
Use the handshake module for client-side handshakes.
…
Usage with Axum
Enable the Axum integration with features = ["upgrade", "with_axum"] in Cargo.toml.
…
No open issues yet, or sync has not completed.