use async_trait::async_trait; use bft_json_crdt::json_crdt::SignedOp; use ezsockets::ClientConfig; use tokio::fs::File; use tokio::io; use tokio::sync::mpsc; use crate::{node::SideNode, utils}; pub(crate) struct WebSocketClient { incoming_sender: mpsc::Sender, } impl WebSocketClient { pub(crate) fn new(incoming_sender: mpsc::Sender) -> Self { Self { incoming_sender } } /// Start the websocket client pub(crate) async fn start(node: &mut SideNode, incoming_sender: mpsc::Sender) { tracing_subscriber::fmt::init(); let config = ClientConfig::new("ws://localhost:8080/websocket"); let (handle, future) = ezsockets::connect(|_client| WebSocketClient { incoming_sender }, config).await; tokio::spawn(async move { future.await.unwrap(); }); let stdin = tokio::io::stdin(); // let lines = stdin.lock().lines(); // let mut reader = FramedRead::new(stdin, LinesCodec::new()); let line = reader.next().await.transpose()?.unwrap(); let signed_op = if let "exit" = line.as_str() { break; } else if let "trace" = line.as_str() { node.trace_crdt(); continue; } else { let fake = utils::fake_transaction("foo123".to_string()); node.add_transaction_local(fake) }; tracing::info!("sending {:?}", signed_op); let json = serde_json::to_string(&signed_op).unwrap(); handle.text(json).unwrap(); } } #[async_trait] impl ezsockets::ClientExt for WebSocketClient { type Call = (); async fn on_text(&mut self, text: String) -> Result<(), ezsockets::Error> { tracing::info!("received message: {text}"); let incoming: bft_json_crdt::json_crdt::SignedOp = serde_json::from_str(&text).unwrap(); tracing::info!("received signed op: {incoming:?}"); self.incoming_sender.send(incoming).await.unwrap(); Ok(()) } async fn on_binary(&mut self, bytes: Vec) -> Result<(), ezsockets::Error> { tracing::info!("received bytes: {bytes:?}"); Ok(()) } async fn on_call(&mut self, call: Self::Call) -> Result<(), ezsockets::Error> { let () = call; Ok(()) } }