remote/B侧设计文档.md

5.4 KiB
Raw Permalink Blame History

B 侧设计文档(主控端 + 协议 + 网络)

负责人:成员 B | 主责 crate:viewer/、common/ | 配合:A(agent/) 按里程碑推进,每个里程碑独立 feature 分支,合入即打 tag。


B1 · 联调基线(1-2 天,和 A 合作完成)

目标:拿到 H.264 版双机实测数据,作为一切优化的对照基线。

  1. HUD 扩展:新增 丢包率(估算)/抖动(jitter)/帧间隔 p95 三项读数
    • 抖动 = 相邻帧 E2E 差值的绝对值 EMA;帧间隔 p95 用环形缓冲取 95 分位;
    • 码流异常计数(解码失败次数)也上 HUD,验证关键帧自愈是否生效。
  2. 测试脚本 tools/bench.md:固定三个场景各测 60s —— 静止桌面 / 播放视频 / 拖动窗口,记录 HUD 截图。
  3. 产出:基线数据表填入本文件末尾。

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。

候选地址与打洞

  1. agent 侧收集候选:本机局域网地址、路由器公网映射(STUN 探测,自建 coturn 的 stun 或公共 stun);
  2. 双方经信令交换候选后同时向对方发探测包(UDP 打洞,锥形 NAT 成功率高;对称 NAT 基本打不通);
  3. 打通 → 直连(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 码率 丢包 抖动
静止桌面
视频播放
拖动窗口