接上一篇继续,今天来学习下如何用axum实现websocket,代码如下:
Cargo.toml添加依赖项
代码语言:javascript复制[package]
name = "websocket"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
axum = {version = "0.4.3", features = ["headers","ws"] }
tokio = { version = "1.0", features = ["full"] }
tracing = "0.1"
tracing-subscriber = { version="0.3", features = ["env-filter"] }
tower-http = { version = "0.2.0", features = ["fs", "trace"] }
headers = "0.3"
关键是axum的features中的ws,接下来是示例代码main.rs
代码语言:javascript复制use axum::{
extract::{
ws::{Message, WebSocket, WebSocketUpgrade},
TypedHeader,
},
response::IntoResponse,
routing::{get},
Router,
};
use std::net::SocketAddr;
use tower_http::{
trace::{DefaultMakeSpan, TraceLayer},
};
#[tokio::main]
async fn main() {
if std::env::var_os("RUST_LOG").is_none() {
std::env::set_var("RUST_LOG", "example_websockets=debug,tower_http=debug")
}
tracing_subscriber::fmt::init();
let app = Router::new()
.route("/", get(|| async { "Hello, World!" }))
//绑定websocket路由
.route("/ws", get(ws_handler))
.layer(
TraceLayer::new_for_http()
.make_span_with(DefaultMakeSpan::default().include_headers(true)),
);
let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
tracing::debug!("listening on {}", addr);
axum::Server::bind(&addr)
.serve(app.into_make_service())
.await
.unwrap();
}
async fn ws_handler(
ws: WebSocketUpgrade,
user_agent: Option<TypedHeader<headers::UserAgent>>,
) -> impl IntoResponse {
if let Some(TypedHeader(user_agent)) = user_agent {
println!("`{}` connected", user_agent.as_str());
}
ws.on_upgrade(handle_socket)
}
async fn handle_socket(mut socket: WebSocket) {
if let Some(msg) = socket.recv().await {
if let Ok(msg) = msg {
println!("Client says: {:?}", msg);
//客户端发什么,服务端就回什么(只是演示而已)
if socket
.send(Message::Text(format!("{:?}", msg)))
.await
.is_err()
{
println!("client disconnected");
return;
}
} else {
println!("client disconnected");
return;
}
}
}
核心就是handle_socket这个function,这里我们只是简单的将收到的内容,原封不动的发回浏览器。
运行一下:
先浏览http://localhost:3000/ 然后F12打开Console控制台,输入下面几行js代码:
代码语言:javascript复制socket = new WebSocket('ws://localhost:3000/ws');
socket.addEventListener('message', function (event) {
console.log('Message from server ', event.data);
});
socket.send('你好,RUST!');
就能看到服务端回过来的内容