use crate::{ net::{ ClientMsg, Msg, ServerMsg, server::{ClientSender, ConAccepter, listen}, transfer::RecvHandler, }, rsc::DataDir, }; use std::{ collections::HashMap, sync::{ Arc, atomic::{AtomicU64, Ordering}, }, }; use tokio::sync::RwLock; #[tokio::main] pub async fn run_server() { let dir = DataDir::default(); let path = dir.get(); let handler = ServerListener { msgs: Default::default(), senders: Default::default(), count: 0.into(), }; listen(path, handler).await; } type ClientId = u64; struct ServerListener { msgs: Arc>>, senders: Arc>>, count: AtomicU64, } impl ConAccepter for ServerListener { async fn accept(&self, send: ClientSender) -> impl RecvHandler { let id = self.count.fetch_add(1, Ordering::Release); self.senders.write().await.insert(id, send.clone()); ClientHandler { msgs: self.msgs.clone(), senders: self.senders.clone(), send, id, } } } struct ClientHandler { msgs: Arc>>, send: ClientSender, senders: Arc>>, id: ClientId, } impl RecvHandler for ClientHandler { async fn msg(&self, msg: ClientMsg) { match msg { ClientMsg::SendMsg(msg) => { self.msgs.write().await.push(msg.clone()); let mut handles = Vec::new(); for (&id, send) in self.senders.read().await.iter() { if id == self.id { continue; } let send = send.clone(); let msg = msg.clone(); let fut = async move { let _ = send.send(ServerMsg::SendMsg(msg)).await; }; handles.push(tokio::spawn(fut)); } for h in handles { h.await.unwrap(); } } ClientMsg::RequestMsgs => { let msgs = self.msgs.read().await.clone(); let _ = self.send.send(ServerMsg::LoadMsgs(msgs)).await; } } } }