1use std::{net::SocketAddr, sync::Arc};
2
3use tokio::net::TcpListener;
4
5use crate::{session::Session, ws::WebSocket};
6
7pub struct SessionServer {
8 listener: TcpListener,
9}
10
11impl SessionServer {
12 pub async fn bind(addr: &str) -> crate::Result<Self> {
13 Ok(Self {
14 listener: TcpListener::bind(addr).await?,
15 })
16 }
17
18 pub async fn accept(&self) -> crate::Result<(Session, SocketAddr)> {
19 let (stream, addr) = self.listener.accept().await?;
20
21 let ws = WebSocket::handshake(stream).await?;
22
23 Ok((Session::from_ws(ws), addr))
24 }
25
26 pub async fn session_loop<Fut: Future<Output = crate::Result<()>> + Send + 'static>(
27 &self,
28 on_conn: impl Fn(Session, SocketAddr) -> Fut + 'static,
29 ) -> crate::Result<()> {
30 let conn_handler = Arc::new(on_conn);
31
32 loop {
33 let (session, addr) = self.accept().await?;
34 let conn_handler = conn_handler.clone();
35
36 session.start_receiver();
37
38 tokio::spawn(conn_handler(session, addr));
39 }
40 }
41}