5.4 KiB
5.4 KiB
B 侧设计文档(主控端 + 协议 + 网络)
负责人:成员 B | 主责 crate:
viewer/、common/| 配合:A(agent/) 按里程碑推进,每个里程碑独立 feature 分支,合入即打 tag。
B1 · 联调基线(1-2 天,和 A 合作完成)
目标:拿到 H.264 版双机实测数据,作为一切优化的对照基线。
- HUD 扩展:新增 丢包率(估算)/抖动(jitter)/帧间隔 p95 三项读数
- 抖动 = 相邻帧 E2E 差值的绝对值 EMA;帧间隔 p95 用环形缓冲取 95 分位;
- 码流异常计数(解码失败次数)也上 HUD,验证关键帧自愈是否生效。
- 测试脚本
tools/bench.md:固定三个场景各测 60s —— 静止桌面 / 播放视频 / 拖动窗口,记录 HUD 截图。 - 产出:基线数据表填入本文件末尾。
B2 · 码率自适应(3-4 天)
目标:弱网自动降码率保流畅,好网缓慢升码率提画质。
协议扩展(common/)
/// B2 新增控制消息(流 2)
RateReport {
loss_permille: u16, // 接收端估算丢包率 ‰
rtt_ms: u32, // 最近 RTT
e2e_ms: u32, // 平滑后端到端延迟
}
viewer 每 2s 汇总一次发送(流 2 复用,无新增握手)。
控制算法(先简后精,AIMD 风格)
| 网络状态(连续 3 个周期) | 动作 |
|---|---|
| 丢包 > 8% 或 E2E > 400ms | 码率 ×0.6(下限 1Mbps),同时通知编码器降帧率到 20fps |
| 丢包 3-8% | 码率 ×0.9 |
| 丢包 < 1% 且 E2E < 150ms 持续 10s | 码率 +500Kbps 步进上探(上限 15Mbps) |
agent 侧配合点(给 A 的接口需求)
- 需要运行时改码率的入口:优先查 openh264 crate 是否暴露
SetOption(RC_PARAM); - 若 crate 不支持 → 方案 B:保留 encoder 实例但按新码率重建(重建成本 ~50ms,降码率不频繁,可接受);
- 降级到极限(1Mbps 仍丢包 >15%)→ 主动降分辨率 1080p→720p(A 实现,协议传
ResChange通知,viewer 重配解码器与窗口尺寸)。
B3 · P2P 打洞 + 信令 + 中继(1.5-2 周,核心里程碑)
目标:跨公网可用。三层结构:
┌─────────┐ ①注册/交换地址(WebSocket) ┌──────────┐
│ viewer │ ───────────────────────────→ │ 信令服务器 │
└────┬────┘ └──────────┘
│ ②拿到对方候选地址(IP:port×N) ↑
│ ③a 直连(打洞) ──────────────────── agent 注册
│ ③b 失败 → 走 TURN 中继
信令服务器(B 主建,A 参与评审)
- 最小实现:单二进制 Rust + WebSocket(tokio-tungstenite),无数据库;
- 消息:
Register{agent_id}/Connect{agent_id}/Answer{candidates, auth_code_hint}; - agent 开机注册自身 ID(设备码),viewer 输对方 ID 发起;
- 中立服务器,不碰媒体数据,带宽成本 ≈ 0。
候选地址与打洞
- agent 侧收集候选:本机局域网地址、路由器公网映射(STUN 探测,自建 coturn 的 stun 或公共 stun);
- 双方经信令交换候选后同时向对方发探测包(UDP 打洞,锥形 NAT 成功率高;对称 NAT 基本打不通);
- 打通 → 直连(QUIC 直接到该地址);打不通 → TURN 中继兜底。
中继方案(务实路线)
QUIC 本身没有标准 TURN 集成,两条路:
- 路线一(推荐先做):自建中继服务
relay—— viewer 把 QUIC 包封装转发给 relay,relay 转给 agent(本质是应用层 TURN,复用信令服务器的部署); - 路线二(二期):coturn + 手写 ICE-lite,仅在路线一性能不足时投入。
安全(随 B3 一起做,替代现在的跳过校验)
- 预共享验证码升级为 PAKE(SPAKE2):验证码不落服务器、不落网络,双方推导会话密钥;
- 信令只传地址候选,媒体端到端加密保持 QUIC TLS 不变。
B4 · 多屏 + 文件传输(各 2-3 天,穿插做)
多屏:
- 协议:
ScreenList{screens: Vec<{id, w, h}>}(AuthOk 里带)、SelectScreen{id}; - agent 枚举 DXGI outputs(A 实现),viewer 加屏幕切换下拉;
- 第二期再做"多屏同显"。
文件传输:
- 首选走已有 QUIC 连接开独立双向流(不引入 aria2 依赖,部署简单);
- 协议:
FileOffer{name, size}→FileAccept→ 原始分块流(1MB 块 + 校验); - viewer 做拖拽发送 + 保存对话框。
里程碑与分支规划
| 里程碑 | 分支 | 预估 | 验收标准 |
|---|---|---|---|
| B1 联调基线 | feature/hud-baseline | 1-2 天 | 三场景基线数据入库 |
| B2 码率自适应 | feature/rate-adapt | 3-4 天 | 模拟弱网(clumsy/丢包工具)下自动降码率,画面不断流 |
| B3 打洞+中继 | feature/p2p-relay | 1.5-2 周 | 两台跨公网机器通过 ID 互联;打洞失败自动走中继 |
| B4 多屏/文件 | feature/screens-files | 3-5 天 | 多屏切换、拖拽传文件可用 |
顺序建议:B1 → B2 → B3 → B4(B3 是价值最大项,B4 可穿插)。
基线数据表(B1 完成后填写)
| 场景 | FPS | RTT | E2E | 码率 | 丢包 | 抖动 |
|---|---|---|---|---|---|---|
| 静止桌面 | ||||||
| 视频播放 | ||||||
| 拖动窗口 |