Niskle互联方案
Niskle Hub × Niskle Link 互联方案
本目录是「在头显内用 Niskle Link 操作 PC 端 Niskle Hub」这个功能的开发资料。 整个目录可以一起发出去,也可以只发某一端方案和它对应的提示词。
文件说明
| 文件 | 面向 | 内容 |
|---|---|---|
01-互联协议规范-v1.md | 两端 | 协议的唯一真相源。接口、信封、错误码、鉴权、能力清单、事件流、演进规则、v1 操作清单 |
02-Niskle Hub 互联方案(PC 端).md | PC 端 | Hub 端实现方案,末尾附可直接投喂给 AI 的提示词 |
03-Niskle Link 互联方案(头显端).md | 头显端 | Link 端实现方案,末尾附可直接投喂给 AI 的提示词 |
改动规则:协议层面的变化只改 01,再同步两端。02 和 03 不重复定义协议。
这个功能要解决什么
戴着 VR 头显玩 PCVR 时,改面捕参数、重启体感追踪、看报错信息这些事, 眼下都要摘掉头显走到电脑前用鼠标做。目标是把它们搬进头显里。
这套协议同时也是后续「头显端新功能」的地基。Link 会持续加功能, 所以设计目标是「加功能不用改协议」。
路线图:将来要加串流,这决定了架构
产品路线是 Link 作为头显端串流接收端,Hub 作为 PC 端串流服务端(对标 Virtual Desktop 的两端)。
所以本次只做控制面,但控制面与未来的媒体面需要完全解耦:
| 平面 | 内容 | 状态 |
|---|---|---|
| 控制面(本次) | 发现、配对、鉴权、能力协商、状态订阅、操作调用 | 本次实现 |
| 媒体面(未来) | 头显接收 PC 的画面与声音 | 已规划,不在本次范围 |
这对实现提出两条约束(协议规范 §15 有完整说明):
控制面的核心逻辑不与 Tauri
AppHandle耦合,拆成core/(纯逻辑)+host_app/(Tauri 适配)。 将来串流在 PC 侧大概率需要一个常驻服务,届时core/可以原样搬进host_service/, 协议和两端实现都不受影响。stream.*命名空间现在就在协议里占位(不实现),这样将来加串流是填实现而不是改协议。
端口方面,未来媒体面划定在 UDP 37100–37199,已在协议 §15.5 占位。
关键设计决策(一句话版)
| 决策 | 结论 |
|---|---|
| 头显里长什么样 | 2D 悬浮面板(普通 Android 应用),不做 OpenXR 沉浸式 |
| 传输 | 局域网 HTTP/1.1 + JSON,下行推送用 SSE |
| 为什么不用 WebSocket | 离线构建缓存里没有 tungstenite;SSE 是 HTTP 子集,头显端零新依赖 |
| 端口 | 控制 21120/TCP(可配置,以 /v1/info 的 port 为准);发现信标 37022/UDP(固定) |
| 鉴权 | PC 显示 6 位配对码 → 头显输入一次 → 换 32 字节长期令牌 |
| 能力清单 | Hub 声明,Link 只用来做门控,不做自动渲染界面 |
| 本地网络 | 仅局域网直连;协议形状已为将来的云端中继预留 |
| 协议文件 | 不建 JSON Schema,01 文档即规范 |
三个硬约束
这三条来自对现有代码的实测审计,方案是绕开它们设计的:
LAN 服务落在 Rust Host 里。 Engine 的命名管道
nMaxInstances=1且拒绝远程客户端(named_pipe_server.cpp:33-40), Rust 是它唯一客户端。头显直连 Engine 会死锁。 链路是:头显 → Rust Host → EngineManager → Engine。头显刷命令会挤掉桌面用户的操作。 Engine 命令队列只有 32 深,溢出时丢弃最旧(
engine_manager.rs:23,419-422)。 协议因此规定了服务端限流与按资源串行化。互斥目前只写在前端(
main.ts里的slimevrBusy等),Rust 侧没有对应物。 头显与桌面 UI 并发操作会互相干扰,串行化需要下沉到 Rust。
另有一个已经存在的安全缺口:SlimeVR 状态桥接监听 0.0.0.0:21112 且没有鉴权,
接受明文 wifi_provision:<ssid>:<密码> 等命令。它只需要被本机访问,改成只监听回环即可
(见协议 §9.5)。
建议的实施顺序
PC 端先做,并在动头显端之前用探针脚本留下证据,这样联调时能立刻分清是哪一端的问题。
| 阶段 | 端 | 内容 |
|---|---|---|
| P0–P3 | Hub | 配对 + 令牌 + RPC 骨架 → 能力清单与操作 → SSE 事件 → UDP 信标 |
| P4–P7 | Link | 发现与配对 → 状态与追踪控制 → 体感追踪 → 更新与设备管理 |
P0–P3 可以用 curl 独立验证,不需要头显配合。
现在还没实现
本目录是设计文档,不是已完成的代码。截至编写时:
Hub 端没有自己的局域网服务(现有 21112 端口属于 SlimeVR Java 进程)
Link 端没有远程控制相关代码,发现机制目前只广播、不监听
两端都没有配对、令牌、能力清单相关的任何代码
两端方案里各自标注了风险与未决问题,那两节值得先看。