use futures_util::{ StreamExt, stream::{ SplitSink, SplitStream, Stream, }, }; use tokio::{ time::{ Duration, interval, }, net::{ TcpListener, TcpStream, }, }; use tokio_tungstenite::{ accept_async_with_config, WebSocketStream, tungstenite::{ Message, Result, Error as WsError, protocol::WebSocketConfig, }, }; use tokio_stream::wrappers::IntervalStream; type WsTx = SplitSink, Message>; type WsRx = SplitStream>; async fn accept(tcp_stream: TcpStream) -> Result, WsError> { let wsconfig = WebSocketConfig { max_send_queue: Some(5), max_message_size: None, max_frame_size: None, accept_unmasked_frames: false, }; accept_async_with_config(tcp_stream, Some(wsconfig)).await } async fn handle(mut rx: WsRx) -> anyhow::Result<()> { println!("enter incoming loop"); while let Some(msg) = rx.next().await { match msg { Ok(Message::Text(x)) => { println!("Got Text Message: {x:?}"); }, Ok(x) => { println!("Got another Message: {x:?}"); }, Err(x) => { println!("Got ERROR: {x:?}"); }, } } Ok(()) } async fn serve>(tx: WsTx, input: S) -> Result<(), WsError> { input .map(Message::Text) .map(Ok) .forward(tx).await } #[tokio::main] async fn main() -> anyhow::Result<()> { let listener = TcpListener::bind("127.0.0.1:8080").await?; while let Ok((tcp_stream, addr)) = listener.accept().await { println!("Got a connection from: {addr}"); let ws_result = accept(tcp_stream).await; let (tx, rx) = ws_result.map(|ws| ws.split())?; // in reality this is an mqtt stream let interval_stream = IntervalStream::new(interval(Duration::from_secs(1))); let stream = interval_stream.zip(futures_util::stream::repeat("djshjh".to_string())) .map(|(i, txt)| format!("{i:?}: {txt}")); tokio::select! { res = handle(rx) => println!("Done waiting for messages. Reason: {res:?}"), _ = serve(tx, stream) => println!("Done serving locations.") } } Ok(()) }