use std::sync::Arc;
use dashmap::DashSet;
use serde::Serialize;
use tokio::sync::mpsc::Sender;
use tokio_tungstenite::tungstenite::Message;
use uuid::Uuid;
use crate::{
error::Result,
server::server_handler::ServerStates,
utils::{broadcast_builder::BroadcastBuilder, send_data::Response},
};
pub(crate) struct PeerState {
socket_id: Uuid,
sender: Sender<Message>,
server_states: Arc<ServerStates>,
rooms: Arc<DashSet<String>>,
}
impl PeerState {
pub(crate) fn new(sender: Sender<Message>, server_states: Arc<ServerStates>) -> Self {
Self {
socket_id: Uuid::new_v4(),
sender,
server_states,
rooms: Arc::new(DashSet::new()),
}
}
pub(crate) fn get_socket_id(&self) -> Uuid {
self.socket_id
}
pub(crate) fn get_rooms(&self) -> Arc<DashSet<String>> {
self.rooms.clone()
}
pub(crate) async fn emit<T: Serialize>(&self, event: &str, data: T) -> Result<()> {
let json = serde_json::to_string(&Response {
event: event.to_string(),
data,
})?;
match self.sender.send(Message::Text(json.into())).await {
Ok(_) => Ok(()),
Err(_) => Err(crate::error::RustWaveError::ConnectionClosed),
}
}
pub(crate) fn join_room(&self, room: &str) {
self.server_states.insert_room(room, self.socket_id);
self.rooms.insert(room.to_string());
}
pub(crate) fn leave_room(&self, room: &str) {
self.server_states.remove_room(room, &self.socket_id);
self.rooms.remove(&room.to_string());
}
pub(crate) fn broadcast<T: Serialize>(&self, event: &str, data: T) -> BroadcastBuilder<T> {
BroadcastBuilder::new(event.to_string(), data, self.server_states.clone())
}
pub(crate) async fn broadcast_to_room<T: Serialize>(
&self,
room: &str,
event: &str,
data: T,
) -> Result<()> {
self.server_states.room_broadcast(room, event, data).await?;
Ok(())
}
pub(crate) async fn broadcast_to_expect<T: Serialize>(
&self,
room: &str,
socket_id: Uuid,
event: &str,
data: T,
) -> Result<()> {
self.server_states
.room_broadcast_except(room, &socket_id, event, data)
.await?;
Ok(())
}
}