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-util (which almost all tokio projects depend on)
- SHA1 backend, e.g. sha1_smol (see Feature flags)
- Big selection of features to tailor dependencies to any project (see Feature flags)
- SIMD support: AVX2 or SSE2 for frame (un)masking and accelerated UTF-8 validation
- Strict conformance with the websocket specification, passes the Autobahn test suite without relaxations by default (some can be enabled for performance)
- 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: no unnecessary duplicate UTF-8 validation, no duplicate bounds checking (this however heavily uses unsafe code, which is sound to my knowledge, if not, open an issue!)
Feature flags
Feature flags in tokio-websockets are added to allow tailoring it to your needs.
simdwill enable AVX2 and SSE2 accelerated masking and UTF-8 validationclientenables a tiny client implementationserverenables a tiny server implementationhttp-integrationenables a method for websocket upgradehttp::Requestgeneration
TLS support 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-certs
One SHA1 implementation is required, usually provided by the TLS implementation:
ringis used ifrustlsis the TLS library- The
opensslfeature will useopenssl, usually prefered 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:
fastrandis the default used and 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
For these reasons, I recommend disabling default features and using a configuration that makes sense for you, for example:
# Tiny client
= { = "*", = false, = ["client", "fastrand", "sha1_smol"] }
# Client with SIMD, cryptographically secure RNG and rustls
= { = "*", = false, = ["client", "getrandom", "simd", "rustls-webpki-roots"] }
Example
This is a simple websocket echo server without any proper error handling.
More examples can be found in the examples folder.
use SinkExt;
use Uri;
use TcpListener;
use ;
async
Caveats / Limitations / ToDo
Currently, WebsocketStream does not implement Stream due to the poll_next nature of the trait, which makes implementing it with actual async code near impossible.
I am waiting for async traits and will implement it once possible. Until then, a method called next already exists and serves as a replacement for futures-util's next, which most users were probably looking for.
Further, websocket compression is currently unsupported.