7 use connect::{tcp::TcpListener, ConnectDatagram, ConnectionReader, ConnectionWriter, StreamExt};
11 sync::{Arc, RwLock, Weak},
14 sync::{broadcast, mpsc, Mutex as AsyncMutex},
22 pub conn: AsyncMutex<ConnectionWriter>,
23 pub server: Weak<ServerData>,
28 async fn login(&self, pkt: &Login) {
29 println!("login {} {}", pkt.name, pkt.pwd);
32 async fn run(&self, mut reader: ConnectionReader) {
33 let mut quit = self.quit.subscribe();
37 Some(msg) = reader.next() => match msg.recipient() {
38 LOGIN if let Some(pkt) = pkt::get::<Login>(&msg) =>
39 self.login(&pkt).await,
42 _ = quit.recv() => break,
47 if let Some(server) = self.server.upgrade() {
48 server.clients_by_id.write().unwrap().remove(&self.id);
51 println!("disconnect {}", self.id);
55 pub struct ServerData {
56 clients_by_id: RwLock<HashMap<ClientId, Arc<Client>>>,
57 clients_by_name: RwLock<HashMap<String, Arc<Client>>>,
61 listener: TcpListener,
62 data: Arc<ServerData>,
67 pub async fn new(addr: &str, quit: Quit) -> Self {
68 println!("listen {addr}");
72 listener: TcpListener::bind(addr).await.unwrap(),
73 data: Arc::new(ServerData {
74 clients_by_id: RwLock::new(HashMap::new()),
75 clients_by_name: RwLock::new(HashMap::new()),
80 pub async fn run(mut self) {
81 let mut next_id: ClientId = 0;
82 let mut quit = self.quit.subscribe();
86 Some(conn) = self.listener.next() => {
87 println!("connect {}", conn.peer_addr());
89 let (reader, writer) = conn.split();
90 let client = Arc::new(Client {
92 conn: AsyncMutex::new(writer),
93 server: Arc::downgrade(&self.data),
94 quit: self.quit.clone(),
101 .insert(next_id, Arc::clone(&client));
105 task::spawn(async move { (*client).run(reader).await });
107 _ = quit.recv() => break,
112 println!("shutdown");