WebSocket
Implementation of RFC6455 and RFC7692.
Activation feature is called web-socket
.
Autobahn Reports
Compression
The "permessage-deflate" extension is the only supported compression format and is backed by the zlib-rs
project that performs as well as zlib-ng
.
To get the most performance possible, try compiling your program with RUSTFLAGS='-C target-cpu=native'
to allow zlib-rs
to use more efficient SIMD instructions.
Client Example
//! WebSocket CLI client that enables real-time communication by allowing users to send and //! receive messages through typing. //! //! This snippet requires ~35 dependencies and has an optimized binary size of ~550K. extern crate tokio; extern crate wtx; extern crate wtx_instances; use tokio::{ io::{AsyncBufReadExt, BufReader}, net::TcpStream, }; use wtx::{ misc::{StdRng, Uri}, web_socket::{ FrameBufferVec, FrameMutVec, HeadersBuffer, OpCode, WebSocketBuffer, WebSocketClient, }, }; #[tokio::main] async fn main() -> wtx::Result<()> { let uri = Uri::new("ws://www.example.com"); let fb = &mut FrameBufferVec::default(); let (_, mut ws) = WebSocketClient::connect( (), fb, [], &mut HeadersBuffer::default(), StdRng::default(), TcpStream::connect(uri.hostname_with_implied_port()).await?, &uri.to_ref(), WebSocketBuffer::default(), ) .await?; let mut buffer = String::new(); let mut reader = BufReader::new(tokio::io::stdin()); loop { tokio::select! { frame_rslt = ws.read_frame(fb) => { let frame = frame_rslt?; match (frame.op_code(), frame.text_payload()) { (_, Some(elem)) => println!("{elem}"), (OpCode::Close, _) => break, _ => {} } } read_rslt = reader.read_line(&mut buffer) => { let _ = read_rslt?; ws.write_frame(&mut FrameMutVec::new_fin(fb, OpCode::Text, buffer.as_bytes())?).await?; } } } Ok(()) }
Server Example
//! Serves requests using low-level WebSockets resources along side self-made certificates. extern crate tokio; extern crate tokio_rustls; extern crate wtx; extern crate wtx_instances; use tokio::net::TcpStream; use tokio_rustls::server::TlsStream; use wtx::{ http::LowLevelServer, misc::{StdRng, TokioRustlsAcceptor}, web_socket::{FrameBufferVec, OpCode, WebSocketBuffer, WebSocketServer}, }; #[tokio::main] async fn main() -> wtx::Result<()> { LowLevelServer::tokio_web_socket( &wtx_instances::host_from_args(), None, || {}, |error| eprintln!("{error}"), handle, ( || { TokioRustlsAcceptor::without_client_auth() .build_with_cert_chain_and_priv_key(wtx_instances::CERT, wtx_instances::KEY) }, |acceptor| acceptor.clone(), |acceptor, stream| async move { Ok(acceptor.accept(stream).await?) }, ), ) .await } async fn handle( fb: &mut FrameBufferVec, mut ws: WebSocketServer<(), StdRng, TlsStream<TcpStream>, &mut WebSocketBuffer>, ) -> wtx::Result<()> { loop { let mut frame = ws.read_frame(fb).await?; match frame.op_code() { OpCode::Binary | OpCode::Text => { ws.write_frame(&mut frame).await?; } OpCode::Close => break, _ => {} } } Ok(()) }