连接与配对设计
September 20, 2026 · View on GitHub
面向:实现者与部署方 · 状态:stable · 最近核对:2026-09-20
决定:只保留一条路
产品上只提供「经公网中转」这一种连接方式,不给用户选。
理由:
- 两边本来都要联网才能用上模型,直连省下的那点流量没有意义;文本流本身很小。
- 两套连接方式意味着两套故障模式、两套排查路径、两套能力差异(文件发送就只在 中转下能用)。支持成本远大于收益。
- 用户在家用 Wi-Fi 时走中转也不担心流量,且体验完全一致。
保留的例外:dsh://direct?... 仍是 DEBUG-only 的启动参数,只供仿真器用例
连接本机 DSH 使用,不出现在任何用户界面里。它是测试通道,不是产品特性。
配对的现状
| 组件 | 现状 |
|---|---|
中转 agents 表 | 存在,且 agentSecret 只存哈希 |
中转 accounts 表 | 存在(agents_account 索引),但未启用 |
| 配对码 | 中转 POST /pair/code 签发(一次性、默认 10 分钟);连接器 /mobile-link/pair-code 取用,手机 /pair/claim 兑换 |
| 二维码 | 连接器 GET /mobile-link/qr 出图,内容是 dsh://pair?relay=…&code=…;App 扫码或手输配对码 |
| 设备令牌 | 已签发,按 agent 归属,长期有效并随 /pair/refresh 轮换 |
| 设备管理 | 中转 GET /devices、POST /devices/revoke + admin.py device-list;App 设置页已可看已配对设备并撤销 |
| 直连入口 | App 连接页已去掉,只保留中转配对;dsh://direct 仅 DEBUG 参数 |
关键缺口:每个用户的 agent 身份目前靠运营者手工预置(admin.py)。
少数几个人可以,公开分发不行——这是多人化的第一道坎。
目标形态
① 用户在电脑上装 DSH + 本项目插件
│
② 首次启动,连接器向中转「登记」,拿到 agentId + agentSecret
│ (需要账号或邀请码,不能完全开放)
▼
③ 连接器在桌面显示一个二维码(含 relayUrl + 一次性配对码)
│
④ 手机 App 扫码 → POST /pair/claim → 拿到 deviceToken
│
⑤ 之后自动重连,无需再配对
为什么是扫码而不是输码
配对码要 8 位、带连字符、还要区分大小写,手输一次成功率很低;而且用户要先把
wss://…/dsh-link 这种地址抄到手机上。二维码把「地址 + 码」一次带过去,
这也是桌面版 DSH 已有的交互方式。
登记(第 ② 步)怎么防滥用
三个层次,按落地顺序:
- 邀请码(最小可用):中转签发一次性邀请码,连接器用它换身份。 成本低,足以支撑早期几十个用户。
- 账号(
accounts表已预留):邮箱/OAuth 登录后签发身份, 便于做设备列表、撤销、配额。 - 限流与配额:按账号限制 agent 数、在线连接数、日流量。
不允许完全开放的匿名登记——中转是公网可达的,开放登记等于把服务器交出去。
需要补的东西
| 项 | 说明 | 状态 |
|---|---|---|
| 连接器自助登记 | 用邀请码换 agentId/secret;admin.py 保留为运营工具 | 未做(公开分发前必做) |
| 二维码 | 连接器 GET /mobile-link/qr 出图;App 扫码 | ✅ 已具备 |
| 设备自助管理 | App 内可看已配对设备、可撤销 | ✅ 已具备 |
| App 去掉直连入口 | 连接页只保留「中转配对」 | ✅ 已具备 |
| 能力探测 | 连接器 status 回报 capabilities,App 据此显示/隐藏功能 | ✅ 已具备 |
| 配额与限流 | 按账号限制 agent 数 / 在线连接数 / 日流量 | 未做(用户量上来再说) |
兼容性备忘
连接器 status 现已回报:
{ "serverVersion": "0.2.0",
"capabilities": ["file-transfer", "events", "session-streams",
"pair-code", "qr-pairing", "self-enroll"] }
(实际清单来自 plugins/mobile-link/lib/hello.js 的 SERVER_CAPABILITIES;
serverVersion 读的是插件 package.json,不是手写常量。)
App 必须做能力探测而非版本比较:老连接器缺某个能力时,对应入口隐藏并说明, 而不是让调用打到 Host 上得到 404。这一条已经踩过——文件功能在旧连接器下只报 「DSH returned HTTP 404」,看不出真正原因。
安全待办
agentSecret/deviceToken已只存哈希(已具备)- 待确认:配对码有效期与一次性语义、失败限流(
_CLAIM_FAILURES已有)、 设备撤销后的令牌失效传播 - 待确认:中转上的会话数据是否落盘(当前为纯转发,应保持不落盘)