宿主通信与状态
WinUI 与 Rust Native Host 通过私有子进程的标准输入/输出通信。当前协议版本为 1。
通道约定
- stdin/stdout 使用按行分隔的 JSON。
- stdout 只传协议响应和事件,日志写入 stderr。
- 请求携带 protocolVersion;响应回传请求 id。
- 启动后进行握手,确认宿主版本、会话、能力和数据位置。
- 无效版本、参数或协议消息必须产生明确错误,不能当作成功继续。
客户端类型见 Core/Protocol/HostMessages.cs,传输见 Core/Transport/StdioHostTransport.cs;宿主实现位于 src-tauri/src/native_host.rs。
根据能力使用功能
握手中的 capabilities 是当前宿主提供能力的依据。客户端要先确认连接和所需能力,再开放操作;不依靠窗口已出现或命令名字存在推断功能可用。
原生宿主只有一份播放/队列权威。界面、沉浸和胶囊共享它,避免各自维护一套独立播放进度。
事件与重连
| 事件 | 用途 |
|---|---|
| playback.changed | 播放状态变化 |
| playback.progress | 播放位置更新 |
| playback.meter | 音频电平 |
| playback.ended | 当前播放结束 |
| session.changed | 会话状态变化 |
| import.progress | 导入进度 |
| storage.watch-changed | 扫描目录变化 |
事件带 sessionId 和递增的 seq。重连后丢弃旧会话事件,避免旧曲目或旧进度覆盖当前状态。高频进度、电平可以合并;停止、结束和其它关键状态不能因此丢失。
超时不是失败的反证
播放、跳转、导入和写入超时后,宿主可能已经执行。先重新读取当前状态、确认结果,再决定下一步;不要自动重复发出带副作用的请求。
断开连接时,界面需要准确表达不可用状态,不能只更新按钮外观而继续假定旧宿主可用。
数据和关闭
宿主启动要求显式数据目录,并使用跨进程独占锁。正式目录受到额外保护,普通 WinUI 预览不放开这个保护。
关闭使用 stdin EOF 或 host_shutdown 等正常路径释放资源;强制终止只是故障兜底。手机接力的配对与同步恢复另有持久化状态,不应把恢复连接视为恢复旧播放事务。
测试什么
覆盖版本不匹配、无效参数、响应归属、迟到事件、宿主退出和未知写入结果。模型测试之外,再用真实宿主进程验证通信,最后检查原生用户入口,不能只靠命令清单宣称迁移完成。