Rust的WebSocket库:tungstenite和tokio-tungstenite
WebSocket是一种协议,通过单个TCP连接在客户端和服务器之间提供全双工通信。在Rust生态系统中,最流行的WebSocket库是tungstenite(同步)和tokio-tungstenite(基于Tokio的异步)。这两个库都提供了用于创建WebSocket服务器和客户端的高级API,支持标准扩展并通过TLS提供安全性。
主要功能
- tungstenite:WebSocket的同步实现(RFC 6455),支持阻塞操作,适用于简单脚本和嵌入式场景。
- tokio-tungstenite:基于tungstenite的异步封装,与Tokio运行时集成,可同时处理数千个连接。
- 支持帧、消息、ping/pong、连接关闭。
- 支持TLS(通过
rustls或native-tls)。 - 支持WebSocket扩展(例如permessage-deflate压缩)。
- 配置简单,依赖最小。
安装
将库添加到Cargo.toml:
[dependencies]tokio-tungstenite = "0.21" # 异步版本tungstenite = "0.21" # 同步版本tokio = { version = "1", features = ["full"] } # 用于tokio-tungstenite异步WebSocket服务器示例(tokio-tungstenite)
创建一个简单的回显服务器,接收文本消息并将其发送回去:
use tokio::net::TcpListener;use tokio_tungstenite::accept_async;use tokio_tungstenite::tungstenite::Message;use futures_util::{SinkExt, StreamExt};
#[tokio::main]async fn main() -> Result<(), Box<dyn std::error::Error>> { let listener = TcpListener::bind("127.0.0.1:9001").await?; println!("WebSocket服务器已启动在 ws://127.0.0.1:9001");
while let Ok((stream, peer)) = listener.accept().await { tokio::spawn(handle_connection(stream, peer)); } Ok(())}
async fn handle_connection(stream: tokio::net::TcpStream, peer: std::net::SocketAddr) { let ws_stream = match accept_async(stream).await { Ok(ws) => ws, Err(e) => { eprintln!("连接 {} 时出错: {}", peer, e); return; } };
let (mut write, mut read) = ws_stream.split(); println!("新连接: {}", peer);
while let Some(msg) = read.next().await { match msg { Ok(Message::Text(text)) => { println!("从 {} 收到: {}", peer, text); if let Err(e) = write.send(Message::Text(text.into())).await { eprintln!("发送错误: {}", e); break; } } Ok(Message::Close(_)) => { println!("客户端 {} 已断开", peer); break; } Err(e) => { eprintln!("错误: {}", e); break; } _ => {} // 忽略二进制和控制消息 } }}同步WebSocket客户端示例(tungstenite)
一个简单的客户端,连接到服务器并发送消息:
use tungstenite::{connect, Message};use url::Url;
fn main() -> Result<(), Box<dyn std::error::Error>> { let url = Url::parse("ws://echo.websocket.org")?; let (mut socket, response) = connect(url)?;
println!("已连接到服务器"); println!("HTTP状态: {}", response.status());
socket.send(Message::Text("你好,WebSocket!".into()))?; println!("消息已发送");
let msg = socket.read()?; if let Message::T