use std::{ collections::HashMap, sync::{Arc, RwLock}, }; use tokio::sync::mpsc::{Sender, channel, Receiver}; use crate::prelude::*; pub type UserId = u64; #[derive(Clone)] pub struct Chats { inner: Arc>, } impl Chats { pub fn new() -> Chats { let subscriptions = HashMap::new(); let chats_inner = ChatsInner { subscriptions, next_sub: 0 }; let inner = Arc::new(RwLock::new(chats_inner)); Chats { inner } } pub fn new_sub(&self) -> (UserId, Receiver) { let mut inner = self.inner.write().unwrap(); let sub_id = inner.next_sub; inner.next_sub += 1; let (rx,tx) = channel(32); inner.subscriptions.insert(sub_id, rx); (sub_id, tx) } pub async fn broadcast(&self, msg: &str) -> Result<()> { let subs = { let inner = self.inner.read().unwrap(); inner.subscriptions.clone() }; for (sub_id, tx) in subs.iter() { tx.send(msg.to_string()).await?; tracing::info!("Sent message to {}", sub_id); } Ok(()) } pub fn remove_sub(&self, sub_id: UserId) { let mut inner = self.inner.write().unwrap(); inner.subscriptions.remove(&sub_id); } } struct ChatsInner { pub next_sub: u64, pub subscriptions: HashMap>, }