187 lines
4.4 KiB
Rust
187 lines
4.4 KiB
Rust
use std::fmt;
|
|
use std::{collections::HashSet, sync::Arc};
|
|
|
|
use serde::Serialize;
|
|
use serde_json::Value;
|
|
|
|
use crate::{
|
|
adapter::BroadcastOptions, error::Result, packet::Packet, server::SocketIo,
|
|
session::Session,
|
|
};
|
|
|
|
#[derive(Clone)]
|
|
pub struct Socket {
|
|
pub io: SocketIo,
|
|
pub session: Arc<Session>,
|
|
pub namespace: String,
|
|
pub sid: String,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
pub enum DisconnectReason {
|
|
Client,
|
|
TransportClosed,
|
|
PingTimeout,
|
|
Server,
|
|
}
|
|
|
|
#[derive(Clone)]
|
|
pub struct AckSender {
|
|
session: Arc<Session>,
|
|
namespace: String,
|
|
id: u64,
|
|
}
|
|
|
|
impl fmt::Debug for AckSender {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
f.debug_struct("AckSender")
|
|
.field("namespace", &self.namespace)
|
|
.field("id", &self.id)
|
|
.finish_non_exhaustive()
|
|
}
|
|
}
|
|
|
|
impl AckSender {
|
|
pub fn new(session: Arc<Session>, namespace: String, id: u64) -> Self {
|
|
Self {
|
|
session,
|
|
namespace,
|
|
id,
|
|
}
|
|
}
|
|
|
|
pub async fn send<T: Serialize>(&self, data: T) -> Result<()> {
|
|
let args = match serde_json::to_value(data)? {
|
|
Value::Array(values) => values,
|
|
value => vec![value],
|
|
};
|
|
self.session
|
|
.enqueue_socket_packet(Packet::ack(&self.namespace, self.id, args))
|
|
.await;
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
impl Socket {
|
|
pub fn id(&self) -> &str {
|
|
&self.sid
|
|
}
|
|
|
|
pub fn namespace(&self) -> &str {
|
|
&self.namespace
|
|
}
|
|
|
|
pub fn session_user(&self) -> Option<uuid::Uuid> {
|
|
self.session
|
|
.user
|
|
.lock()
|
|
.unwrap_or_else(|e| e.into_inner())
|
|
.clone()
|
|
}
|
|
|
|
pub fn set_user(&self, user: uuid::Uuid) {
|
|
*self.session.user.lock().unwrap_or_else(|e| e.into_inner()) =
|
|
Some(user);
|
|
}
|
|
|
|
pub async fn rooms(&self) -> HashSet<String> {
|
|
self.session
|
|
.namespaces
|
|
.lock()
|
|
.await
|
|
.get(&self.namespace)
|
|
.map(|state| state.rooms.clone())
|
|
.unwrap_or_default()
|
|
}
|
|
|
|
pub async fn auth(&self) -> Option<Value> {
|
|
self.session
|
|
.namespaces
|
|
.lock()
|
|
.await
|
|
.get(&self.namespace)
|
|
.and_then(|state| state.auth.clone())
|
|
}
|
|
|
|
pub async fn emit<T: Serialize>(&self, event: &str, data: T) -> Result<()> {
|
|
self.io
|
|
.emit_to_sid(&self.namespace, &self.session.engine_id, event, data)
|
|
.await
|
|
}
|
|
|
|
pub async fn emit_with_ack<T: Serialize>(
|
|
&self,
|
|
event: &str,
|
|
data: T,
|
|
) -> Result<Vec<Value>> {
|
|
self.io
|
|
.emit_to_sid_with_ack(
|
|
&self.namespace,
|
|
&self.session.engine_id,
|
|
event,
|
|
data,
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn emit_binary(
|
|
&self,
|
|
event: &str,
|
|
args: Vec<Value>,
|
|
binary: Vec<Vec<u8>>,
|
|
) -> Result<()> {
|
|
self.io
|
|
.emit_binary_to_sid(
|
|
&self.namespace,
|
|
&self.session.engine_id,
|
|
event,
|
|
args,
|
|
binary,
|
|
)
|
|
.await
|
|
}
|
|
|
|
pub async fn broadcast<T: Serialize>(
|
|
&self,
|
|
event: &str,
|
|
data: T,
|
|
) -> Result<()> {
|
|
let opts = BroadcastOptions {
|
|
namespace: self.namespace.clone(),
|
|
skip_sid: Some(self.session.engine_id.clone()),
|
|
..BroadcastOptions::default()
|
|
};
|
|
self.io.broadcast_with_opts(opts, event, data).await
|
|
}
|
|
|
|
pub async fn join(&self, room: impl Into<String>) -> Result<()> {
|
|
self.io
|
|
.join(&self.namespace, &self.session.engine_id, room.into())
|
|
.await
|
|
}
|
|
|
|
pub async fn leave(&self, room: &str) -> Result<()> {
|
|
self.io
|
|
.leave(&self.namespace, &self.session.engine_id, room)
|
|
.await
|
|
}
|
|
|
|
pub async fn disconnect(&self) -> Result<()> {
|
|
self.session
|
|
.enqueue_socket_packet(Packet::new(
|
|
crate::packet::PacketType::Disconnect,
|
|
&self.namespace,
|
|
None,
|
|
None,
|
|
))
|
|
.await;
|
|
self.io
|
|
.disconnect_socket(
|
|
&self.namespace,
|
|
&self.session,
|
|
DisconnectReason::Server,
|
|
)
|
|
.await
|
|
}
|
|
}
|