Expand description
§tokio-websockets
High performance, strict, tokio-util based WebSockets implementation.
§Why use tokio-websockets?
- Built with tokio-util, intended to be used with tokio from the ground up
- Minimal dependencies: The base only requires:
tokio,tokio-util,bytes,futures-core,futures-sink,simdutf8- SHA1 backend, e.g.
sha1_smol(see Feature flags)
- Big selection of features to tailor dependencies to any project (see Feature flags)
- SIMD support for frame (un)masking and accelerated UTF-8 validation (see SIMD)
- Strict conformance with the WebSocket specification, passes the Autobahn test suite without relaxations by default
- TLS support
- Reusable TLS connectors
- Uses widely known crates from the ecosystem for types, for example
Urifromhttpin the client - Cheaply clonable messages due to
Bytesas payload storage - Tuned for performance (see the benchmarks)
§Feature flags
Feature flags in tokio-websockets are added to allow tailoring it to your needs.
- The
nightlyfeature when using a nightly compiler will enable SIMD accelerated masking and UTF-8 validation on additional targets (see SIMD) clientenables a tiny client implementationserverenables a tiny server implementation
TLS is supported via any of the following feature flags:
native-tlsfor atokio-native-tlsbacked implementationrustls-webpki-rootsfor atokio-rustlsbacked implementation withwebpki-rootsrustls-native-rootsfor atokio-rustlsbacked implementation withrustls-native-certsrustls-platform-verifierfor atokio-rustlsbacked implementation withrustls-platform-verifierrustls-bring-your-own-connectorfor atokio-rustlsbacked implementation that requires you to create your ownConnector::Rustls- theConnector::newmethod will return a plain connector
The rustls-*-roots and rustls-platform-verifier features require installing a crypto provider for rustls, see here for more information.
One SHA1 implementation is required, usually provided by the TLS implementation:
ringoraws_lc_rsare used if theringoraws_lc_rsfeatures are enabled (recommended whenrustlsis used)- The
opensslfeature will useopenssl, usually preferred on most Linux/BSD systems withnative-tls - The
sha1_smolfeature can be used as a fallback if no TLS is needed
The client feature requires enabling one random number generator:
fastrandcan be used as aPRNGgetrandomcan be used as a cryptographically secure RNGrandcan be used as an alternative tofastrandand should be preferred if it is already in the dependency tree
§SIMD
tokio-websockets makes use of SIMD to accelerate (un-)masking of messages and UTF-8 validation.
| Architecture | Instructions | (Un-)masking | UTF-8 validation |
|---|---|---|---|
| aarch64 | NEON | ✅ | ✅ |
| arm | NEON | ✅ (on nightly) | ✅ (on nightly) |
| loongarch64 | LASX | ✅ (on nightly) | ❌ |
| powerpc | AltiVec | ✅ (on nightly) | ❌ |
| powerpc64 | AltiVec | ✅ (on nightly) | ❌ |
| powerpc64le | AltiVec | ✅ (on nightly) | ❌ |
| s390x | z13 vectors | ✅ (on nightly) | ❌ |
| x86_64 | SSE2 | ✅ | ❌ |
| x86_64 | AVX2 | ✅ | ✅ |
| x86_64 | AVX512 | ✅ (on nightly) | ❌ |
§Example
This is a simple WebSocket echo server without any proper error handling.
More examples can be found in the examples folder.
use futures_util::{SinkExt, StreamExt};
use http::Uri;
use tokio::net::TcpListener;
use tokio_websockets::{ClientBuilder, Error, Message, ServerBuilder};
#[tokio::main]
async fn main() -> Result<(), Error> {
let listener = TcpListener::bind("127.0.0.1:3000").await?;
tokio::spawn(async move {
while let Ok((stream, _)) = listener.accept().await {
let (_request, mut ws_stream) = ServerBuilder::new()
.accept(stream)
.await?;
tokio::spawn(async move {
// Just an echo server, really
while let Some(Ok(msg)) = ws_stream.next().await {
if msg.is_text() || msg.is_binary() {
ws_stream.send(msg).await?;
}
}
Ok::<_, Error>(())
});
}
Ok::<_, Error>(())
});
let uri = Uri::from_static("ws://127.0.0.1:3000");
let (mut client, _) = ClientBuilder::from_uri(uri).connect().await?;
client.send(Message::text("Hello world!")).await?;
while let Some(Ok(msg)) = client.next().await {
if let Some(text) = msg.as_text() {
assert_eq!(text, "Hello world!");
// We got one message, just stop now
client.close().await?;
}
}
Ok(())
}§MSRV
The current MSRV for all feature combinations is Rust 1.79.
§Caveats / Limitations / ToDo
WebSocket compression is currently unsupported.
Re-exports§
pub use client::Builder as ClientBuilder;clientpub use error::Error;pub use proto::CloseCode;pub use proto::Config;pub use proto::Limits;pub use proto::Message;pub use proto::Payload;pub use proto::WebSocketStream;pub use server::Builder as ServerBuilder;serverpub use tls::Connector;pub use tls::MaybeTlsStream;
Modules§
- client
client - Implementation of a WebSocket client.
- error
- General error type used in the crate.
- proto
- This module contains a correct and complete implementation of RFC6455.
- resolver
client - Abstractions over DNS resolvers.
- server
server - Implementation of a WebSocket server.
- tls
- Wrapper types for TLS functionality, abstracting over
rustlsandnative-tlsconnector and stream types. - upgrade
clientorserver - HTTP upgrade request and response generation and validation helpers.