use serde::Deserialize; /// 聊天连接的心跳周期。存活的在线占位与 presence 状态都按它的两倍续期, /// 由 `online_ttl_secs()` 派生。 #[derive(Clone, Debug, Deserialize)] #[serde(default)] pub struct ChatWsConfig { pub heartbeat_secs: u64, } impl Default for ChatWsConfig { fn default() -> Self { Self { heartbeat_secs: 30 } } } #[derive(Clone, Debug, Deserialize)] #[serde(default)] pub struct ChatUploadConfig { pub max_size: i64, pub presign_ttl_secs: u64, } impl Default for ChatUploadConfig { fn default() -> Self { Self { max_size: 104_857_600, presign_ttl_secs: 3600, } } } #[derive(Clone, Debug, Deserialize)] #[serde(default)] pub struct ChatConfig { pub max_pagination: u64, pub default_pagination: u64, pub max_message_len: usize, pub max_topic_len: usize, pub max_thread_name_len: usize, pub max_reaction_emoji_len: usize, pub max_emoji_name_len: usize, pub max_bookmark_title_len: usize, pub max_webhook_name_len: usize, pub max_mentions_per_message: usize, pub max_attachments_per_message: usize, pub max_members_per_add: usize, pub max_pending_attachments_per_user: i64, pub typing_ttl_secs: u64, pub presence_ttl_secs: u64, pub ws: ChatWsConfig, pub upload: ChatUploadConfig, } impl Default for ChatConfig { fn default() -> Self { Self { max_pagination: 200, default_pagination: 50, max_message_len: 4000, max_topic_len: 1024, max_thread_name_len: 255, max_reaction_emoji_len: 64, max_emoji_name_len: 64, max_bookmark_title_len: 255, max_webhook_name_len: 100, max_mentions_per_message: 20, max_attachments_per_message: 10, max_members_per_add: 50, max_pending_attachments_per_user: 200, typing_ttl_secs: 5, presence_ttl_secs: 300, ws: ChatWsConfig::default(), upload: ChatUploadConfig::default(), } } } impl ChatConfig { /// 聊天 WS 在线占位与可见在线状态的 TTL:两倍心跳——丢一个 tick 不掉线, /// 进程崩溃后最多两个心跳周期就会由 TTL 兜底回到离线。 /// /// 与 `presence_ttl_secs` 的区别:那个是"手动设置一次状态"的存活时间, /// 这个只用于跟随 WS 生命周期的自动续期。 pub fn online_ttl_secs(&self) -> u64 { self.ws.heartbeat_secs.max(5).saturating_mul(2) } } impl ChatConfig { pub fn is_valid(&self) -> Result<(), String> { if self.max_pagination == 0 || self.default_pagination == 0 { return Err("chat pagination must be positive".to_string()); } if self.max_message_len == 0 { return Err("chat max_message_len must be positive".to_string()); } if self.ws.heartbeat_secs == 0 { return Err("chat ws heartbeat_secs must be positive".to_string()); } Ok(()) } }