Recipe: chat room
WebSocket echo + broadcast room from
examples/chat.
Dependencies
[dependencies]
churust = { version = "0.3", features = ["ws"] }
Code
use churust::prelude::*; use churust::tokio::sync::broadcast; use churust::ws::{Message, WebSocketUpgrade}; use std::sync::Arc; #[derive(Clone)] struct Room { tx: Arc<broadcast::Sender<String>>, } #[churust::main] async fn main() -> std::io::Result<()> { let (tx, _rx) = broadcast::channel::<String>(100); Churust::server() .host("127.0.0.1") .port(8080) .state(Room { tx: Arc::new(tx) }) .routing(|r| { r.get("/echo", |ws: WebSocketUpgrade| async move { ws.on_upgrade(|mut sock| async move { while let Some(Ok(msg)) = sock.recv().await { if matches!(msg, Message::Close) { break; } if sock.send(msg).await.is_err() { break; } } }) }); r.get( "/room", |room: State<Room>, ws: WebSocketUpgrade| async move { let tx = room.tx.clone(); let mut rx = tx.subscribe(); ws.on_upgrade(move |mut sock| async move { loop { churust::tokio::select! { incoming = sock.recv() => match incoming { Some(Ok(Message::Text(t))) => { let _ = tx.send(t); } Some(Ok(Message::Close)) | None => break, Some(Err(_)) => break, _ => {} }, outgoing = rx.recv() => { if let Ok(text) = outgoing { if sock.send_text(text).await.is_err() { break; } } } } } }) }, ); }) .start() .await }
Try it
cargo run -p chat
websocat ws://localhost:8080/echo
# two terminals:
websocat ws://localhost:8080/room
Plain HTTP GET → 426 Upgrade Required.