use std::{ collections::{HashMap, HashSet, VecDeque}, sync::Arc, sync::Mutex as StdMutex, sync::atomic::AtomicBool, time::Instant, }; use serde_json::Value; use tokio::sync::{Mutex, Notify, oneshot}; use uuid::Uuid; use crate::{ engine_packet::{EnginePacket, SocketPayload}, packet::Packet, }; #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum Transport { Polling, WebSocket, } #[derive(Debug)] pub struct SocketState { pub sid: String, pub rooms: HashSet, pub auth: Option, } pub struct PendingBinary { pub packet: Packet, } pub struct Session { pub engine_id: String, pub user: StdMutex>, pub transport: Mutex, pub namespaces: Mutex>, pub pending_binary: Mutex>, pub ack_waiters: Mutex, pub last_pong: Mutex, queue: Mutex>, pub get_active: Arc, pub post_active: Arc, pub notify: Notify, } pub type AckWaiters = HashMap<(String, u64), oneshot::Sender>>; impl Session { pub fn new(user: Option) -> Arc { Arc::new(Self { engine_id: Uuid::new_v4().to_string(), user: StdMutex::new(user), transport: Mutex::new(Transport::Polling), namespaces: Mutex::new(HashMap::new()), pending_binary: Mutex::new(None), ack_waiters: Mutex::new(HashMap::new()), last_pong: Mutex::new(Instant::now()), queue: Mutex::new(VecDeque::new()), get_active: Arc::new(AtomicBool::new(false)), post_active: Arc::new(AtomicBool::new(false)), notify: Notify::new(), }) } pub async fn enqueue(&self, packet: EnginePacket) { self.queue.lock().await.push_back(packet); self.notify.notify_waiters(); } pub async fn enqueue_socket_packet(&self, packet: Packet) { self.enqueue(EnginePacket::Message(SocketPayload::Text( packet.encode(), ))) .await; for attachment in packet.attachments { self.enqueue(EnginePacket::Message(SocketPayload::Binary( attachment, ))) .await; } } pub async fn drain(&self) -> Vec { self.queue.lock().await.drain(..).collect() } }