Skip to main content

stynx_code_bridge/application/
bridge_main.rs

1use std::collections::HashMap;
2use std::sync::Arc;
3use tokio::net::TcpListener;
4use tokio::sync::RwLock;
5use stynx_code_errors::AppResult;
6use crate::domain::session::BridgeSession;
7use crate::infrastructure::websocket_transport::WebSocketTransport;
8use crate::application::bridge_messaging::{BridgeMessageHandler, DefaultBridgeHandler};
9
10pub struct BridgeServer {
11    pub port: u16,
12    pub sessions: Arc<RwLock<HashMap<String, BridgeSession>>>,
13}
14
15impl BridgeServer {
16    pub fn new(port: u16) -> Self {
17        Self {
18            port,
19            sessions: Arc::new(RwLock::new(HashMap::new())),
20        }
21    }
22
23    pub async fn start(port: u16) -> AppResult<()> {
24        let addr = format!("127.0.0.1:{}", port);
25        let listener = TcpListener::bind(&addr).await
26            .map_err(|e| stynx_code_errors::AppError::Internal(anyhow::anyhow!(e)))?;
27        tracing::info!(addr, "bridge server listening");
28
29        loop {
30            let (stream, peer) = listener.accept().await
31                .map_err(|e| stynx_code_errors::AppError::Internal(anyhow::anyhow!(e)))?;
32            tracing::info!(%peer, "new connection");
33
34            tokio::spawn(async move {
35                let transport = WebSocketTransport::new();
36                match transport.accept_connection(stream).await {
37                    Ok(mut conn) => {
38                        let handler = DefaultBridgeHandler;
39                        loop {
40                            match conn.recv().await {
41                                Some(msg) => {
42                                    match handler.handle_message(msg).await {
43                                        Ok(response) => {
44                                            if let Err(e) = conn.send(response).await {
45                                                tracing::error!(?e, "send error");
46                                                break;
47                                            }
48                                        }
49                                        Err(e) => {
50                                            tracing::error!(?e, "handler error");
51                                            break;
52                                        }
53                                    }
54                                }
55                                None => {
56                                    tracing::info!("connection closed");
57                                    break;
58                                }
59                            }
60                        }
61                    }
62                    Err(e) => {
63                        tracing::error!(?e, "websocket upgrade failed");
64                    }
65                }
66            });
67        }
68    }
69
70    pub async fn stop(&self) {
71        tracing::info!("bridge server stopping");
72        self.sessions.write().await.clear();
73    }
74}