//! WebSocket 通信协议。 //! //! 服务端与客户端之间通过 WebSocket 交换消息: //! - 客户端发送 [`ClientMessage`](输入、调整尺寸、声明控制权); //! - 服务端发送 [`ServerMessage`](就绪、移动端快照、控制权授予、错误、会话结束)。 //! //! 另外,为 PC 端提供**二进制**通道:PTY 输出的原始 ANSI 字节流直接以 WebSocket //! 二进制帧下发,供 `flutter_alacritty` 等渲染引擎消费,保证 100% 工业级兼容。 use serde::{Deserialize, Serialize}; /// 客户端发送给 Rtty 服务端的控制指令。 #[derive(Debug, Deserialize)] #[serde(tag = "type", rename_all = "snake_case")] pub enum ClientMessage { /// 键盘/文本输入,原样写入 PTY。 Input { data: String }, /// 客户端请求调整终端尺寸。 Resize { cols: u16, rows: u16 }, /// 客户端申明控制权(用来解决多端控制冲突)。 ClaimControl, /// 客户端心跳,保持连接活跃。 Ping, } /// 移动端语义化屏显数据(已解耦、去除 ANSI 序列)。 #[derive(Debug, Clone, Serialize)] pub struct MobileSnapshot { /// 光标列(相对视口)。 pub cursor_x: usize, /// 光标行(相对视口)。 pub cursor_y: usize, /// 网格列数。 pub cols: usize, /// 网格行数。 pub rows: usize, /// 当前回滚显示偏移。 pub display_offset: usize, /// 滚动历史中的总行数。 pub scrollback_lines: usize, /// 视口内的逐行文本(已按词、去尾空白)。 pub lines: Vec, } /// 服务端推送给客户端的消息(JSON 文本帧)。 #[derive(Debug, Serialize)] #[serde(tag = "type", rename_all = "snake_case")] pub enum ServerMessage { /// 会话已就绪:携带会话 ID 与初始尺寸。 Ready { id: String, cols: u16, rows: u16, }, /// 移动端专属:解耦后的语义化屏显快照。 MobileSnapshot { data: MobileSnapshot, }, /// 控制权授予结果。 ControlResponse { granted: bool, holder: Option, }, /// 服务端错误。 Error { message: String, }, /// 会话已结束(PTY 关闭)。 SessionClosed, } impl ServerMessage { /// 序列化为 JSON 文本。 pub fn to_json(&self) -> String { serde_json::to_string(self).unwrap_or_else(|_| "{}".to_string()) } }