宿主通信与状态

协议握手、请求响应、会话事件与能力判断。

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 等正常路径释放资源;强制终止只是故障兜底。手机接力的配对与同步恢复另有持久化状态,不应把恢复连接视为恢复旧播放事务。

测试什么

覆盖版本不匹配、无效参数、响应归属、迟到事件、宿主退出和未知写入结果。模型测试之外,再用真实宿主进程验证通信,最后检查原生用户入口,不能只靠命令清单宣称迁移完成。