Gelbpunkt/tokio-websockets · 文件 下载 ZIP
文件最后提交记录最后更新时间
README.md
以下内容由 AI 翻译,如有问题请点此提交 issue 反馈
tokio-websockets
高性能、严格、基于 tokio-util 的 WebSockets 实现。
为什么使用 tokio-websockets?
- 基于 tokio-util 构建,旨在从底层与 tokio 配合使用
- 依赖项极少:基础部分仅需要:
tokio、tokio-util、bytes、futures-core、futures-sink、simdutf8- SHA1 后端,例如
sha1_smol(参见 Feature flags)
- 丰富的功能选项,可根据任何项目定制依赖项(参见 Feature flags)
- 支持 SIMD 进行帧(解)掩码处理以及加速的 UTF-8 验证(参见 SIMD)
- 严格遵循 WebSocket 规范,默认情况下通过 Autobahn 测试套件 且无需放宽限制 by default
- 支持 TLS
- 可复用的 TLS 连接器
- 使用生态系统中广为人知的 crate 作为类型,例如客户端中的
http中的Uri - 由于使用
Bytes作为负载存储,消息可低成本克隆 - 针对性能进行了调优(参见 基准测试)
Feature flags
tokio-websockets 中的 Feature flags 旨在允许根据您的需求进行定制。
- 使用 nightly 编译器时,
nightly功能将在更多目标上启用 SIMD 加速的掩码处理和 UTF-8 验证(参见 SIMD) client启用一个小型客户端实现server启用一个小型服务器实现
TLS 通过以下任一 Feature flag 支持:
native-tls用于tokio-native-tls支持的实现rustls-webpki-roots用于带有webpki-roots的tokio-rustls支持的实现rustls-native-roots用于带有rustls-native-certs的tokio-rustls支持的实现rustls-platform-verifier用于带有rustls-platform-verifier的tokio-rustls支持的实现rustls-bring-your-own-connector用于需要您自行创建Connector::Rustls的tokio-rustls支持的实现 -Connector::new方法将返回一个普通连接器
rustls-*-roots 和 rustls-platform-verifier 功能需要为 rustls 安装全局 crypto provider,您可以通过在所选的 provider 上调用 CryptoProvider::install_default() 来实现。
需要一个 SHA1 实现,通常由 TLS 实现或其 crypto provider 提供:
- 如果启用了
ring或aws_lc_rs功能,则使用ring或aws_lc_rs(在同时用于rustls时推荐) openssl功能将使用openssl,在大多数带有native-tls的 Linux/BSD 系统上通常更受青睐- 如果不需要 TLS,可以使用
sha1_smol功能作为回退方案
client 功能需要启用一个随机数生成器:
fastrand可以作为PRNG使用getrandom可以作为密码学安全的 RNG 使用- 启用
nightly功能后,std::random可以作为密码学安全的 RNG 使用 rand可以作为fastrand的替代方案,如果它已经在依赖树中,则应优先使用
SIMD
tokio-websockets 利用 SIMD 来加速消息的(去)掩码处理和 UTF-8 验证。
| 架构 | 指令集 | (非)掩码 | UTF-8 验证 |
|---|---|---|---|
| aarch64 | NEON | ✅ | ✅ |
| arm | NEON | ✅ (on nightly) | ✅ (on nightly) |
| loongarch64 | LSX | ✅ (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 | ✅ | ❌ |
示例
更多示例可以在 examples 文件夹 中找到。
一个简单的 WebSocket 回显服务器,没有任何适当的错误处理:
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(())
}
使用 rustls 和以 aws_lc_rs 作为加密提供程序的基本客户端:
use futures_util::{SinkExt, StreamExt};
use http::Uri;
use tokio_websockets::{ClientBuilder, Error, Message};
#[tokio::main]
async fn main() -> Result<(), Error> {
// Will set the default crypto provider for libraries which configure rustls
rustls::crypto::aws_lc_rs::default_provider()
.install_default()
.unwrap();
// Connecting to a echo server with TLS set up
let uri = Uri::from_static("wss://ws.vi-server.org/mirror");
let (mut client, _) = ClientBuilder::from_uri(uri).connect().await?;
// Print out if its a plain or TLS socket
// Requires a TLS feature to be turned on to not be plain
println!("{:?}", client.get_ref());
client.send(Message::text("Hello, world!")).await?;
let msg = client.next().await;
println!("Got echo response: {msg:?}");
client.close().await?;
Ok(())
}
MSRV
当前所有功能组合的 MSRV 为 Rust 1.89。
注意事项 / 限制 / 待办
目前不支持 WebSocket 压缩。