diff --git a/POC_in_rust/Cargo.toml b/POC_in_rust/Cargo.toml index 1ac4834..eb96ea9 100644 --- a/POC_in_rust/Cargo.toml +++ b/POC_in_rust/Cargo.toml @@ -4,6 +4,7 @@ version = "0.1.0" edition = "2024" [dependencies] +async-tungstenite = {version="0.29.1", features=["tokio-rustls-webpki-roots"]} chrono = "0.4.41" env_logger = "0.11.8" futures-lite = "2.6.0" @@ -12,6 +13,7 @@ lazy_static = "1.5.0" nusb = "0.1.13" reqwest = { version = "0.12.15", features = ["json", "multipart", "http2", "cookies"] } reqwest-middleware = "0.4.2" +rustls = "0.23.27" serde = {version = "1.0.219", features=["derive"]} serde_json = "1.0.140" tokio = {version = "1.45.0", features=["time", "fs", "io-util", "macros"]} diff --git a/POC_in_rust/config.json b/POC_in_rust/config.json index de0a1a9..9f55208 100644 --- a/POC_in_rust/config.json +++ b/POC_in_rust/config.json @@ -3,6 +3,5 @@ "SAVING_INTERVAL": 60, "STATION_ID": 2, "HOST": "https://beta.alkator.cz", - "LOGIN": "station_register@alkator.cz", - "PASSWORD": "password_heslo" + "WSS_HOST": "wss://beta.alkator.cz" } \ No newline at end of file diff --git a/POC_in_rust/src/config.rs b/POC_in_rust/src/config.rs index 41b88ea..f69e959 100644 --- a/POC_in_rust/src/config.rs +++ b/POC_in_rust/src/config.rs @@ -12,8 +12,7 @@ pub struct Config { pub SAVING_INTERVAL: u64, pub STATION_ID: usize, pub HOST: String, - pub LOGIN: String, - pub PASSWORD: String, + pub WSS_HOST: String, } fn read_config_from_file>(path: P) -> Result> { diff --git a/POC_in_rust/src/db_update.rs b/POC_in_rust/src/db_update.rs index e69de29..f0cf0ca 100644 --- a/POC_in_rust/src/db_update.rs +++ b/POC_in_rust/src/db_update.rs @@ -0,0 +1,50 @@ +use iced::futures; +use iced::task::{Never, Sipper, sipper}; + +use futures::stream::StreamExt; + +use async_tungstenite::tungstenite; +use crate::config::CONFIG; + +pub fn connect() -> impl Sipper { + sipper(async |mut output| { + let endpoint_addr: String = CONFIG.WSS_HOST.clone() + "/api/live/racers"; + loop { + + let mut websocket = + match async_tungstenite::tokio::connect_async(endpoint_addr.as_str()).await + { + Ok((websocket, _)) => { + websocket.fuse() + } + Err(_) => { + tokio::time::sleep(tokio::time::Duration::from_secs(1)) + .await; + continue; + } + }; + println!("Websocket Connected!"); + loop { + futures::select! { + received = websocket.select_next_some() => { + match received { + Ok(tungstenite::Message::Text(message)) => { + output.send(Event::MessageReceived(String::from(message.as_str()))).await; + } + Err(_) => { + println!("Websocket Disconnected!"); + break; + } + Ok(_) => {}, + } + } + } + } + } + }) +} + +#[derive(Debug, Clone)] +pub enum Event { + MessageReceived(String), +} diff --git a/POC_in_rust/src/main.rs b/POC_in_rust/src/main.rs index 350a163..e93c7f8 100644 --- a/POC_in_rust/src/main.rs +++ b/POC_in_rust/src/main.rs @@ -67,16 +67,21 @@ async fn station_register(card_id: usize, time: DateTime::) -> Result<(), .json(®ister_racer) .send() .await?; + // Result can be error (400 and so on), whatever for now Ok(()) } impl State{ fn update(&mut self, message: Message) -> Task{ match message { - Message::RacerAdded(racer) => { - self.db.insert(racer.card_id, racer); - Task::none() - }, + Message::RacerRecieved(event) => { + match event { + db_update::Event::MessageReceived(s) => { + let racer: Racer = serde_json::from_str(s.as_str()).unwrap(); + self.db.insert(racer.card_id, racer); + }, + }; + } Message::Tick(time) => { if let Some(racer_time) = self.racers.iter().next() { if time - racer_time.time > Duration::new(CONFIG.DURATION + 10, 0){ @@ -95,8 +100,10 @@ impl State{ let time = Instant::now(); let datetime = Local::now(); if let Some(racer) = self.db.get(&card_id){ - let racer_time = RacerTime{time, racer: racer.clone()}; - self.racers.push(racer_time); + if !self.racers.iter().any(|rt| rt.racer.card_id == card_id){ + let racer_time = RacerTime{time, racer: racer.clone()}; + self.racers.push(racer_time); + } }else{ println!("Racer {} not found in db!", card_id) } @@ -153,6 +160,7 @@ impl State{ time::every(milliseconds(10)).map(Message::Tick), time::every(seconds(CONFIG.SAVING_INTERVAL)).map(Message::DumpState), Subscription::run(card_reader::connect).map(Message::CardReader), + Subscription::run(db_update::connect).map(Message::RacerRecieved) ]) } fn theme(&self) -> Theme { @@ -168,7 +176,7 @@ struct Racer{ enum Message{ CardReader(card_reader::Event), - RacerAdded(Racer), + RacerRecieved(db_update::Event), Tick(Instant), DumpState(Instant), Nothing, @@ -185,6 +193,7 @@ impl std::fmt::Debug for Message { pub fn main() -> iced::Result { let init_state = || -> State {read_to_string("state.json").ok().map(|s| serde_json::from_str(&s).ok()).flatten().unwrap_or_else(||Default::default())} ; env_logger::init(); + rustls::crypto::aws_lc_rs::default_provider().install_default().unwrap(); iced::application(init_state, State::update, State::view) .subscription(State::subscription) .theme(State::theme)