rust websocket 和http 监听同一端口代码
时间: 2023-09-22 10:15:24 浏览: 375
以下是一个使用 Rust 中的 tokio 和 warp 库同时监听 WebSocket 和 HTTP 请求的示例代码:
```rust
use std::net::SocketAddr;
use warp::Filter;
use tokio::sync::broadcast;
use tokio_stream::wrappers::BroadcastStream;
use tokio_tungstenite::tungstenite::protocol::Message;
use tokio_tungstenite::{WebSocketStream, MaybeTlsStream};
use tokio_tungstenite::tungstenite::handshake::server::Request;
async fn handle_ws(
ws: WebSocketStream<MaybeTlsStream<tokio::net::TcpStream>>,
tx: broadcast::Sender<Message>,
) {
let (mut ws_tx, mut ws_rx) = ws.split();
let (tx_clone, mut rx) = tx.subscribe();
tokio::spawn(async move {
while let Some(message) = rx.recv().await {
if let Err(e) = ws_tx.send(message).await {
eprintln!("websocket send error: {}", e);
break;
}
}
});
while let Some(Ok(message)) = ws_rx.next().await {
if let Err(e) = tx_clone.send(message).unwrap() {
eprintln!("broadcast send error: {}", e);
break;
}
}
}
#[tokio::main]
async fn main() {
let (tx, _) = broadcast::channel(16);
let ws_route = warp::path("ws")
.and(warp::ws())
.map(move |ws: warp::ws::Ws| {
let tx = tx.clone();
ws.on_upgrade(move |websocket| handle_ws(websocket, tx))
});
let http_route = warp::path("hello")
.map(|| "Hello, world!");
let routes = ws_route.or(http_route);
let addr = SocketAddr::from(([0, 0, 0, 0], 8080));
warp::serve(routes).run(addr).await;
}
```
在这个示例中,我们使用 `tokio_tungstenite` 库来创建 WebSocket 服务器,使用 `warp` 库创建 HTTP 服务器。在 `handle_ws` 函数中,我们使用 `tokio::sync::broadcast` 来实现将 WebSocket 消息广播给所有连接的客户端。最后,我们将 WebSocket 和 HTTP 的路由组合在一起,并使用 `warp::serve` 启动服务器。
需要注意的是,使用同一端口同时监听 WebSocket 和 HTTP 请求并不是一个标准做法,因为 WebSocket 协议需要和 HTTP 协议进行握手,并且 WebSocket 协议有自己的帧格式和消息语义。因此,如果你需要同时支持 WebSocket 和 HTTP 请求,最好是使用不同的端口或使用不同的路径进行区分。
阅读全文