use axum::body::Bytes; use dashmap::DashMap; use std::sync::Arc; use tokio::sync::broadcast; use uuid::Uuid; use crate::routes::messages::Message; #[derive(Clone)] pub struct RealtimeMessages { pub clients: Arc>>, } type VoicePacket = (Uuid, Bytes); #[derive(Clone)] pub struct RealTimeVoices { pub rooms: Arc>>, } impl RealtimeMessages { pub fn new() -> Self { Self { clients: Arc::new(DashMap::new()), } } /// Get or create the sender for a given user pub fn get_sender(&self, user_uuid: Uuid) -> broadcast::Sender { self.clients .entry(user_uuid) .or_insert_with(|| broadcast::channel(100).0) .clone() } /// Send a message to all the recipients pub fn broadcast(&self, recipient_uuids: Vec, message: Message) { for user_uuid in recipient_uuids { if let Some(sender) = self.clients.get(&user_uuid) { let _ = sender.send(message.clone()); } } } } impl Default for RealtimeMessages { fn default() -> Self { Self::new() } } impl RealTimeVoices { pub fn new() -> Self { Self { rooms: Arc::new(DashMap::new()), } } /// Get or create the broadcast sender for a given room pub fn get_or_create_room(&self, room_uuid: Uuid) -> broadcast::Sender { self.rooms .entry(room_uuid) .or_insert_with(|| broadcast::channel(500).0) .clone() } /// Clean up empty rooms pub fn retain_active(&self) { self.rooms.retain(|_, sender| sender.receiver_count() > 0); } } impl Default for RealTimeVoices { fn default() -> Self { Self::new() } }