From 5deebb0621fbf57f10f09b243d199b3b4822562a Mon Sep 17 00:00:00 2001 From: htom Date: Wed, 26 Nov 2025 13:55:39 +0100 Subject: [PATCH] connecting with websocket to local hosted server instance --- ui/Cargo.toml | 1 + ui/src/connection.rs | 96 ++++++++++++++++++++++++++++++++++++++++++++ ui/src/main.rs | 28 ++++++++----- 3 files changed, 116 insertions(+), 9 deletions(-) create mode 100644 ui/src/connection.rs diff --git a/ui/Cargo.toml b/ui/Cargo.toml index 5cf216b..97f9116 100644 --- a/ui/Cargo.toml +++ b/ui/Cargo.toml @@ -19,3 +19,4 @@ engine = {path = "../engine/"} log = {version = "0.4.28"} env_logger = "0.11.8" local-ip-address = "0.6.5" +anyhow = "1.0.100" diff --git a/ui/src/connection.rs b/ui/src/connection.rs new file mode 100644 index 0000000..1e20221 --- /dev/null +++ b/ui/src/connection.rs @@ -0,0 +1,96 @@ +use engine::{chessmove::ChessMove, gameend::GameEnd}; +use futures_util::StreamExt; +use local_ip_address::local_ip; +use log::{error, info, warn}; +use serde::{Deserialize, Serialize}; +use std::{ + error::Error, + net::{IpAddr, Ipv4Addr}, +}; +use tokio_tungstenite::connect_async; +use url::Url; +use uuid::Uuid; + +#[derive(Serialize, Deserialize)] +pub enum ServerMessage2 { + GameEnd { + winner: GameEnd, + }, + UIUpdate { + fen: String, + }, + MatchFound { + match_id: Uuid, + color: String, + opponent_name: String, + }, + Ok { + response: Result<(), String>, + }, +} + +#[derive(Serialize, Deserialize)] +#[serde(tag = "type")] +enum ClientMessage { + Join { username: String }, + FindMatch, + Move { step: ChessMove, fen: String }, + Resign, + Chat { text: String }, + RequestLegalMoves { fen: String }, +} + +fn get_ip_address() -> IpAddr { + let ip = local_ip().unwrap_or(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0))); + + ip +} + +pub async fn handle_connection(server_port: &str) -> anyhow::Result<()> { + let address = get_ip_address(); + + //start main loop + let server_address = String::from("ws://") + &address.to_string() + ":" + server_port; + warn!( + "Machine IpAddress is bound for listener. Ip: {}", + server_address + ); + + let url = Url::parse(&server_address)?; + + let (ws_stream, _) = connect_async(url).await?; + let (mut write, mut read) = ws_stream.split(); + + let read_handle = while let Some(message) = read.next().await { + info!("connection"); + match message { + Ok(msg) => { + if msg.is_text() { + let text = msg.to_text().unwrap(); + info!("text: {}", text); + + if let Ok(parsed) = serde_json::from_str::(text) { + match parsed { + ServerMessage2::GameEnd { winner } => {} + ServerMessage2::UIUpdate { fen } => {} + ServerMessage2::MatchFound { + match_id, + color, + opponent_name, + } => {} + ServerMessage2::Ok { response } => {} + _ => { + error!("Received unkown servermessage2"); + } + } + } + } + } + Err(e) => { + error!("Error receiving message: {}", e); + } + } + }; + + Ok(()) +} diff --git a/ui/src/main.rs b/ui/src/main.rs index cc61876..fa89e55 100644 --- a/ui/src/main.rs +++ b/ui/src/main.rs @@ -1,19 +1,20 @@ use eframe::egui; use env_logger::Env; -use log::{error, info}; +use log::{error, info, warn}; -fn main() -> eframe::Result<()> { +use crate::connection::handle_connection; +mod connection; + +#[tokio::main] +async fn main() -> anyhow::Result<(), eframe::Error> { //set up for logging let env = Env::default().filter_or("MY_LOG_LEVEL", "INFO"); env_logger::init_from_env(env); - info!("Initialized logger"); - - //create a TCPlistener with tokio and bind machine ip for connection - //for this we need to query the ip + warn!("Initialized logger"); let options = eframe::NativeOptions { viewport: egui::ViewportBuilder::default() - .with_fullscreen(true) + .with_fullscreen(false) .with_min_inner_size(egui::vec2(800.0, 600.0)) // Minimum width, height .with_inner_size(egui::vec2(7680.0, 4320.0)), // Initial size ..Default::default() @@ -119,7 +120,7 @@ impl Default for ChessApp { selected: None, turn: Turn::White, pending_settings: PendingSettings::default(), - server_port: "8080".to_string(), // Default port + server_port: "9001".to_string(), // Default port } } } @@ -211,6 +212,15 @@ impl eframe::App for ChessApp { .add_sized([300.0, 60.0], egui::Button::new("Play")) .clicked() { + let port = self.server_port.clone(); + info!("\nstarting connection\n"); + + //create a TCPlistener with tokio and bind machine ip for connection + tokio::spawn(async move { + info!("tokoi"); + handle_connection(&port).await + }); + self.state = AppState::InGame; } ui.add_space(8.0); @@ -279,7 +289,7 @@ impl eframe::App for ChessApp { ui.add( egui::TextEdit::singleline(&mut self.pending_settings.server_port) .desired_width(100.0) - .hint_text("8080"), + .hint_text("9001"), ); }); ui.add_space(30.0);