Skip to content
Clone
main
73 lines 2.8 KB Rust
use std::time::Duration;
pub const MIN_HEARTBEAT_INTERVAL: Duration = Duration::from_secs(30);
pub const MAX_HEARTBEAT_GAP: Duration = Duration::from_secs(60);
pub const DEFAULT_HEARTBEAT_TIMEOUT: Duration = Duration::from_secs(30);
pub const DEFAULT_AUTH_TIMEOUT: Duration = Duration::from_secs(5);
pub const DEFAULT_MAX_PAYLOAD: usize = 1_000_000;
/// 浏览器握手带不了 `Authorization`,所以允许从会话 cookie 取同一个 access token。
pub const DEFAULT_SESSION_COOKIE: &str = config::event::socket::DEFAULT_SESSION_COOKIE;
#[derive(Debug, Clone)]
pub struct SocketOptions {
pub heartbeat_interval: Duration,
pub heartbeat_timeout: Duration,
pub auth_timeout: Duration,
pub max_payload: usize,
/// 承载 KenApi 会话键的 cookie 名(与平台 `session.cookie_name` 一致)。
pub session_cookie: String,
}
impl Default for SocketOptions {
fn default() -> Self {
Self {
heartbeat_interval: MIN_HEARTBEAT_INTERVAL,
heartbeat_timeout: DEFAULT_HEARTBEAT_TIMEOUT,
auth_timeout: DEFAULT_AUTH_TIMEOUT,
max_payload: DEFAULT_MAX_PAYLOAD,
session_cookie: DEFAULT_SESSION_COOKIE.to_string(),
}
}
}
impl SocketOptions {
pub fn validate(&self) -> Result<(), String> {
if self.heartbeat_interval < MIN_HEARTBEAT_INTERVAL {
return Err("socket.heartbeat_interval must be at least 30 seconds".to_string());
}
if self.heartbeat_timeout.is_zero() {
return Err("socket.heartbeat_timeout must be greater than zero".to_string());
}
let gap = self
.heartbeat_interval
.checked_add(self.heartbeat_timeout)
.ok_or_else(|| "socket heartbeat durations overflow".to_string())?;
if gap > MAX_HEARTBEAT_GAP {
return Err(
"socket heartbeat interval and timeout must not exceed 60 seconds".to_string(),
);
}
if self.auth_timeout.is_zero() {
return Err("socket.auth_timeout must be greater than zero".to_string());
}
if self.max_payload == 0 {
return Err("socket.max_payload must be greater than zero".to_string());
}
if self.session_cookie.trim().is_empty() {
return Err("socket.session_cookie must not be blank".to_string());
}
Ok(())
}
}
impl From<&config::event::socket::SocketConfig> for SocketOptions {
fn from(config: &config::event::socket::SocketConfig) -> Self {
Self {
heartbeat_interval: config.heartbeat_interval(),
heartbeat_timeout: config.heartbeat_timeout(),
auth_timeout: config.auth_timeout(),
max_payload: config.max_payload,
session_cookie: config.session_cookie.clone(),
}
}
}