# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
-axum = { version = "0.5", features = ["headers"] }
+axum = { version = "0.5", features = ["ws", "headers"] }
tokio = { version = "1", features = ["full"] }
tower = "0.4"
tower-http = { version = "0.3", features = ["trace", "fs"] }
use axum::{
routing::{get, get_service},
- extract::{Path, TypedHeader},
+ extract::{Path, TypedHeader, ws},
http::{StatusCode},
response,
Router};
}
}
+async fn ws_echo(mut socket: ws::WebSocket) {
+ while let Some(msg) = socket.recv().await {
+ if let Ok(msg) = msg {
+ tracing::debug!("websocket got message: {:?}", msg);
+
+ let reply = match msg {
+ ws::Message::Text(t) => ws::Message::Text(t),
+ ws::Message::Binary(b) => ws::Message::Binary(b),
+ // axum handles Ping/Pong by itself
+ ws::Message::Ping(_) => { continue },
+ ws::Message::Pong(_) => { continue },
+ ws::Message::Close(_) => { break }
+ };
+
+ if socket.send(reply).await
+ .is_err() {
+ tracing::info!("websocket client disconnected");
+ break;
+ }
+ }
+ else {
+ tracing::info!("websocket client disconnected");
+ break;
+ }
+ }
+}
+
#[tokio::main]
async fn main() {
tracing_subscriber::fmt::init();
(StatusCode::INTERNAL_SERVER_ERROR, format!("Unhandled internal error: {}", e))
})
)
+ .route("/ws-echo", get(|ws: ws::WebSocketUpgrade| async {ws.on_upgrade(ws_echo)}))
.layer(
tower::ServiceBuilder::new()
.layer(