// use actix_web::{rt, web, App, Error, HttpRequest, HttpResponse, HttpServer}; use actix_ws::AggregatedMessage; use futures_util::StreamExt as _; async fn echo(req: HttpRequest, stream: web::Payload) -> Result { let (res, mut session, stream) = actix_ws::handle(&req, stream)?; let mut stream = stream .aggregate_continuations() // aggregate continuation frames up to 1MiB .max_continuation_size(2_usize.pow(20)); // start task but don't wait for it rt::spawn(async move { // receive messages from websocket while let Some(msg) = stream.next().await { match msg { Ok(AggregatedMessage::Text(text)) => { // echo text message session.text(text).await.unwrap(); } Ok(AggregatedMessage::Binary(bin)) => { // echo binary message session.binary(bin).await.unwrap(); } Ok(AggregatedMessage::Ping(msg)) => { // respond to PING frame with PONG frame session.pong(&msg).await.unwrap(); } _ => {} } } }); // respond immediately with response connected to WS session Ok(res) } #[actix_web::main] async fn main() -> std::io::Result<()> { HttpServer::new(|| App::new().route("/echo", web::get().to(echo))) .bind(("127.0.0.1", 8080))? .run() .await } // // testing requires specific headers: // Upgrade: websocket // Connection: Upgrade // Sec-WebSocket-Key: SOME_KEY // Sec-WebSocket-Version: 13