| 
									
										
										
										
											2023-02-24 04:17:22 +01:00
										 |  |  | use futures_util::{
 | 
					
						
							|  |  |  |     StreamExt,
 | 
					
						
							|  |  |  |     stream::{
 | 
					
						
							|  |  |  |         SplitSink,
 | 
					
						
							|  |  |  |         SplitStream,
 | 
					
						
							| 
									
										
										
										
											2023-02-25 03:49:25 +01:00
										 |  |  |         Stream,
 | 
					
						
							| 
									
										
										
										
											2023-02-24 04:17:22 +01:00
										 |  |  |     },
 | 
					
						
							|  |  |  | };
 | 
					
						
							|  |  |  | use tokio::{
 | 
					
						
							|  |  |  |     time::{
 | 
					
						
							|  |  |  |         Duration,
 | 
					
						
							| 
									
										
										
										
											2023-02-25 03:49:25 +01:00
										 |  |  |         interval,
 | 
					
						
							| 
									
										
										
										
											2023-02-24 04:17:22 +01:00
										 |  |  |     },
 | 
					
						
							|  |  |  |     net::{
 | 
					
						
							|  |  |  |         TcpListener,
 | 
					
						
							|  |  |  |         TcpStream,
 | 
					
						
							|  |  |  |     },
 | 
					
						
							|  |  |  | };
 | 
					
						
							|  |  |  | use tokio_tungstenite::{
 | 
					
						
							|  |  |  |     accept_async_with_config,
 | 
					
						
							|  |  |  |     WebSocketStream,
 | 
					
						
							|  |  |  |     tungstenite::{
 | 
					
						
							|  |  |  |         Message,
 | 
					
						
							|  |  |  |         Result,
 | 
					
						
							|  |  |  |         Error as WsError,
 | 
					
						
							|  |  |  |         protocol::WebSocketConfig,
 | 
					
						
							|  |  |  |     },
 | 
					
						
							|  |  |  | };
 | 
					
						
							| 
									
										
										
										
											2023-02-25 03:49:25 +01:00
										 |  |  | use tokio_stream::wrappers::IntervalStream;
 | 
					
						
							| 
									
										
										
										
											2023-02-24 04:17:22 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-25 03:49:25 +01:00
										 |  |  | type WsTx = SplitSink<WebSocketStream<tokio::net::TcpStream>, Message>;
 | 
					
						
							|  |  |  | type WsRx = SplitStream<WebSocketStream<tokio::net::TcpStream>>;
 | 
					
						
							| 
									
										
										
										
											2023-02-24 04:17:22 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | async fn accept(tcp_stream: TcpStream) -> Result<WebSocketStream<TcpStream>, 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
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-25 03:49:25 +01:00
										 |  |  | async fn handle(mut rx: WsRx) -> anyhow::Result<()> {
 | 
					
						
							| 
									
										
										
										
											2023-02-24 04:17:22 +01:00
										 |  |  |     println!("enter incoming loop");
 | 
					
						
							|  |  |  |     while let Some(msg) = rx.next().await {
 | 
					
						
							| 
									
										
										
										
											2023-02-25 03:49:25 +01:00
										 |  |  |         match msg {
 | 
					
						
							|  |  |  |             Ok(Message::Text(x)) => { println!("Got Text Message: {x:?}"); },
 | 
					
						
							|  |  |  |             Ok(x) => { println!("Got another Message: {x:?}"); },
 | 
					
						
							|  |  |  |             Err(x) => { println!("Got ERROR: {x:?}"); },
 | 
					
						
							|  |  |  |         }
 | 
					
						
							| 
									
										
										
										
											2023-02-24 04:17:22 +01:00
										 |  |  |     }
 | 
					
						
							|  |  |  |     Ok(())
 | 
					
						
							|  |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-25 03:49:25 +01:00
										 |  |  | async fn serve<S: Stream<Item = String>>(tx: WsTx, input: S) -> Result<(), WsError> {
 | 
					
						
							|  |  |  |     input
 | 
					
						
							|  |  |  |         .map(Message::Text)
 | 
					
						
							|  |  |  |         .map(Ok)
 | 
					
						
							|  |  |  |         .forward(tx).await
 | 
					
						
							| 
									
										
										
										
											2023-02-24 04:17:22 +01:00
										 |  |  | }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #[tokio::main]
 | 
					
						
							| 
									
										
										
										
											2023-02-25 03:49:25 +01:00
										 |  |  | async fn main() -> anyhow::Result<()> {
 | 
					
						
							| 
									
										
										
										
											2023-02-24 04:17:22 +01:00
										 |  |  |     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;
 | 
					
						
							| 
									
										
										
										
											2023-02-25 03:49:25 +01:00
										 |  |  |         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}"));
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-02-24 04:17:22 +01:00
										 |  |  |         tokio::select! {
 | 
					
						
							|  |  |  |             res = handle(rx) => println!("Done waiting for messages. Reason: {res:?}"),
 | 
					
						
							| 
									
										
										
										
											2023-02-25 03:49:25 +01:00
										 |  |  |             _ = serve(tx, stream) => println!("Done serving locations.")
 | 
					
						
							| 
									
										
										
										
											2023-02-24 04:17:22 +01:00
										 |  |  |         }
 | 
					
						
							|  |  |  |     }
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Ok(())
 | 
					
						
							|  |  |  | }
 |