From d1e80e86e989dc0a425429dbac3b5252bfc232c4 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Mon, 12 Dec 2022 08:35:58 +0100 Subject: [PATCH] actix-server: Add "reverse input" websocket route --- actix-server/src/main.rs | 54 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/actix-server/src/main.rs b/actix-server/src/main.rs index 58756de..af63efd 100644 --- a/actix-server/src/main.rs +++ b/actix-server/src/main.rs @@ -66,6 +66,40 @@ async fn ws_echo(req: HttpRequest, stream: web::Payload) -> Result; +} + +impl StreamHandler> for WsRev { + fn handle(&mut self, msg: Result, ctx: &mut Self::Context) { + log::info!("WsRev got message {:?}", msg); + match msg { + Ok(ws::Message::Ping(msg)) => ctx.pong(&msg), + Ok(ws::Message::Text(text)) => { + let rev = text.chars().rev().collect::(); + ctx.text(rev); + }, + Ok(ws::Message::Binary(bin)) => { + let mut rev = bin.to_vec(); + rev.reverse(); + ctx.binary(rev); + } + Ok(ws::Message::Close(reason)) => { + ctx.close(reason); + ctx.stop(); + }, + _ => ctx.stop(), + } + } +} + +#[get("/ws-rev")] +async fn ws_rev(req: HttpRequest, stream: web::Payload) -> Result { + ws::start(WsRev {}, &req, stream) +} + #[actix_web::main] async fn main() -> std::io::Result<()> { env_logger::init_from_env(env_logger::Env::default().default_filter_or("info")); @@ -76,6 +110,7 @@ async fn main() -> std::io::Result<()> { .service(static_file) .service(Files::new("/dir", "../static")) .service(ws_echo) + .service(ws_rev) .wrap(Logger::default()) }) .bind(("127.0.0.1", 3030))? @@ -92,7 +127,7 @@ mod tests { use futures_util::sink::SinkExt; use futures_util::StreamExt; - use super::{hello, static_file, ws_echo}; + use super::{hello, static_file, ws_echo, ws_rev}; #[actix_web::test] async fn test_hello() { @@ -183,4 +218,21 @@ mod tests { let received = client.next().await.unwrap().unwrap(); assert_eq!(received, ws::Frame::Binary(web::Bytes::from_static(&[42, 99]))); } + + #[actix_web::test] + async fn test_ws_rev() { + // FIXME: duplicating the .service() call from main() here is super ugly, but it's hard to move that into a fn + let mut srv = actix_test::start(|| App::new().service(ws_rev)); + let mut client = srv.ws_at("/ws-rev").await.unwrap(); + + // text reversed + client.send(ws::Message::Text("hello".into())).await.unwrap(); + let received = client.next().await.unwrap().unwrap(); + assert_eq!(received, ws::Frame::Text("olleh".into())); + + // binary reversed + client.send(ws::Message::Binary(web::Bytes::from_static(&[42, 99]))).await.unwrap(); + let received = client.next().await.unwrap().unwrap(); + assert_eq!(received, ws::Frame::Binary(web::Bytes::from_static(&[99, 42]))); + } } -- 2.39.2