Files
RemoteDesk/docs/network-adaptation.md
T
曾志威 19a8e03a83
ci / rust (push) Canceled after 0s
ci / web (push) Canceled after 0s
ci / package-preview (push) Canceled after 0s
ci / package-installer (push) Canceled after 0s
ci / linux-agent (push) Canceled after 0s
ci / edge-service (push) Canceled after 0s
ci / coturn-pop (push) Canceled after 0s
ci / package-windows-host (push) Canceled after 0s
Document all-Rust migration and extend native media stack
2026-08-14 14:31:57 +08:00

219 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# RemoteDesk 差网络自适应设计
## 1. 目标
RemoteDesk 在延迟、抖动、随机丢包和突发丢包变化时保持会话可控制。优先级固定为:
```text
键盘/鼠标按键 > 控制与心跳 > 音频 > 视频实时性 > 视频清晰度 > 剪贴板 > 文件传输
```
目标不是在任意丢包率下维持最高画质,而是在恶化时快速退化、避免断开,在恢复时平稳升档。
## 2. 两类连接
### 2.1 Linux Native Channel
Linux 桌面使用 WebRTC,可以利用 RTP/RTCP、TWCC、GCC、NACK、RTX、PLI 和 Opus FEC。RemoteDesk 不重新实现底层拥塞控制,只在 GStreamer/WebRTC 的带宽估算上增加产品级质量策略。
同一策略适用于 Direct、Single Edge 和 Dual Edge。质量报告增加 path mode、两端 POP、TURN transport、骨干指标和 ICE restart 次数,用于区分最后一公里问题、POP 间路径问题和端点过载。
### 2.2 Windows RDP
RDP 的网络恢复能力由 IronRDP 协议实现决定。M0 必须验证:
- RDP UDP multitransport。
- 图形管线在丢包和重连后的恢复行为。
### 2.3 Windows Headless Hysteria2
Windows Headless 使用 Hysteria2 作为网络承载,但应用层必须保持输入、音频和视频分流:
control stream:输入、心跳、配置和 KeyframeRequest,可靠且最高优先级。
audio pathOpus,独立 jitter buffer,允许 PLC/FEC。
video datagramH.264/HEVC/AV1,允许丢包和丢帧。
file stream:文件和剪贴板,可靠、最低优先级、限速。
视频不能放入会因丢包而阻塞后续数据的可靠流。Hysteria2 的 datagram 能力必须由具体 adapter 验证;不能仅因为底层使用 UDP 就假设应用已经具备不可靠语义。若某部署只能提供可靠 QUIC streamWindows Headless 视频通道不得宣称实时丢包模式。
视频分片带有 stream_id、generation、frame_id、fragment_id、fragment_count、PTS 和关键帧标记。缺少任意分片时丢弃整个视频帧;重组超时或帧已过期时立即丢弃;不重传过期视频包。关键帧或参考链损坏后通过控制流请求 IDR。
无硬件 GPU 时 compatibility 模式会进一步受 CPU 编码预算限制。编码器报告 software/degraded 后,质量控制器必须优先降低视频帧率和分辨率,再降低码率;视频队列不得因 CPU 编码变慢而无限增长。输入控制和 Opus 音频保持独立调度,软件编码过载时可以丢弃过期视频帧,但不能阻塞输入或音频。
Hysteria2 的带宽和队列不能让视频占满控制面。输入预留最高优先级,音频次之,视频使用有界队列,文件只使用剩余带宽。必须监控路径 RTT、抖动、队列延迟、包丢失、输入延迟和音画偏差,而不是只观察总吞吐。
- 动态调整视觉效果、色深或编码模式的能力。
- UDP 不可用时 TCP 模式的延迟和队头阻塞表现。
若 IronRDP 尚不支持关键网络能力,差网络场景使用系统 mstsc 回退,并在客户端明确显示当前 Adapter。
## 3. 质量指标
每秒收集原始指标,并计算短期、中期 EWMA:
| 指标 | 来源 | 用途 |
|---|---|---|
| RTT | RTCP/DataChannel heartbeat | 交互延迟和重传收益 |
| Packet loss | RTCP report | 退档和恢复判断 |
| Jitter | RTCP report | jitter buffer 和帧率判断 |
| Available bitrate | TWCC/GCC | 编码码率上限 |
| NACK/RTX rate | RTP feedback | 判断持续丢包与重传成本 |
| PLI/FIR | decoder feedback | 请求关键帧和诊断解码失败 |
| Decode/render time | Windows Client | 判断客户端过载而非网络问题 |
| Send/encode queue | Linux Agent | 判断编码或上行拥塞 |
| DataChannel buffered amount | SCTP | 限制文件与剪贴板流量 |
网络问题、编码器过载和解码器过载必须分别诊断,不能全部显示成“网络差”。
## 4. 链路状态机
默认状态分级仅作为初始调参基线:
| 状态 | 参考信号 | 行为 |
|---|---|---|
| Good | 丢包 <1%RTT/抖动稳定 | 缓慢提高码率或分辨率 |
| Fair | 丢包 1%~5% 或抖动上升 | 降低码率,保持分辨率和输入响应 |
| Poor | 丢包 5%12% 或连续 PLI | 降帧率/分辨率,启用适合的恢复机制 |
| Critical | 丢包 >12%、RTT 激增或反馈中断 | 最低视频档,暂停文件传输,准备重连 |
真实决策组合使用可用码率、RTT、抖动和队列,不只看一个丢包数字。
状态转换规则:
- 恶化使用短窗口,连续多个样本后快速降档。
- 恢复使用更长窗口,稳定后一次只升一档。
- 刚升档后设置冷却时间,防止立刻回落。
- 用户设置的最大分辨率、帧率和码率始终是硬上限。
- 窗口不在前台时主动降低帧率,不归类为网络退化。
## 5. 视频自适应
质量控制器管理三个独立维度:
1. 码率:优先调整,支持编码器运行时更新。
2. 帧率:动态画面从 60 降至 30/20/15 fps。
3. 分辨率:码率不足时按档位降采样,不频繁重建会话。
建议的初始阶梯:
```text
2160p60 -> 2160p30 -> 1440p30 -> 1080p30 -> 720p30 -> 720p15
```
实际起始档由显示器、编码器和用户上限决定。办公静态桌面可以降低刷新频率但保持较高分辨率;动态画面可以优先保持帧率并降低清晰度。
用户分辨率策略与自适应的关系:
- 自动跟随:稳定窗口尺寸作为当前目标和上限,窗口拖动期间不连续重配编码器。
- 原始分辨率:源桌面尺寸作为上限;本地窗口缩放不触发源尺寸变化。
- 固定/自定义:所选宽高是编码目标和硬上限,网络恢复也不能自动升得更高。
- 允许自适应降档(默认):Poor/Critical 状态可临时低于用户目标,恢复后逐级回到目标。
- 锁定分辨率:不自动降尺寸,优先降低码率和帧率;若仍超出带宽则明确提示卡顿/画质风险。
Linux 的自适应只重配 GPU video processor/scaler、DMA-BUF caps 和硬件编码器,不调用 Wayland 合成器设置或 XRandR 改变实体显示模式。分辨率切换保留控制通道,完成后发送新 generation、实际编码尺寸并请求关键帧。Agent 和客户端在新 generation 上重新验证 `EndpointMemoryPath`;若任一端变成 CPU/cross-GPU copy,严格会话暂停媒体并失败,不能为了降分辨率静默破坏零拷贝。接收端在首个新尺寸关键帧到达前保持最后一帧,避免短暂黑屏。
编码器策略:
- 编码码率跟随 GCC target,但保留音频和控制余量。
- GOP 不宜过长,避免丢失参考帧后长期花屏。
- 收到 PLI/FIR 时请求 IDR,但限制关键帧频率,防止反馈风暴。
- 丢弃已过期的待编码帧,实时性优先于完整性。
- 只在短 RTT 下积极使用 RTX;高 RTT 下过时重传价值较低。
- FEC 通过能力协商启用,并计入总带宽,不默认无条件开启。
## 6. 音频
- Opus 使用独立 RTP 流和较高优先级。
- 差网络时优先降低视频,不先中断音频。
- 按协商结果启用 Opus in-band FEC。
- 静音或无音频时使用 DTX 降低占用。
- jitter buffer 自适应但设置交互场景最大延迟上限。
## 7. 输入和控制
输入消息按语义选择可靠性:
| 消息 | 可靠性 |
|---|---|
| 键盘按下/释放 | 可靠、有序 |
| 鼠标按键 | 可靠、有序 |
| 鼠标绝对位置 | 可丢弃旧值,最新值优先 |
| 鼠标相对移动 | 短时有序,过期不重传 |
| 滚轮 | 有序,限制短时合并 |
| 分辨率/显示器 | 可靠、有序 |
| 心跳/会话控制 | 可靠、独立 channel |
断线或重连时,客户端与 Agent 交换完整按键/鼠标状态,主动释放可能卡住的按键。
## 8. 剪贴板和文件
- 与输入使用不同 DataChannel,避免队头阻塞。
- 设置 `bufferedAmount` 高水位,超过后暂停生产数据。
- Poor 状态限制剪贴板图片和文件带宽。
- Critical 状态暂停文件传输,但保留取消和状态消息。
- 恢复后继续按已确认分块序号传输,不重发整个文件。
- 大量粘贴不能挤占终端交互消息。
## 9. 重连
```text
Connected
-> Degraded
-> Reconnecting
-> Connected | Failed
```
- 短时反馈丢失先进入 Degraded,不立即关闭会话。
- WebRTC 尝试 ICE restart;直接连接环境仍可能因接口变化需要重建 PeerConnection。
- Direct candidate 失败时可以切换 TURN POPPOP 故障时请求备用 POP credential 后再次 ICE restart。
- 重连期间 Linux session 进程保留有限时间,编码暂停或降到最低。
- 成功后先恢复输入/控制,再恢复音频和视频。
- 重连后请求关键帧,并同步显示器与输入状态。
- 超过最大宽限期明确结束,不无限占用远端资源。
## 10. 用户设置
提供简单预设,不要求用户理解协议参数:
- 自动:默认,自适应所有档位。
- 清晰:提高最低分辨率,允许更低帧率。
- 流畅:保持目标帧率,允许更快降分辨率。
- 低带宽:限制最大码率、分辨率和文件速度。
分辨率设置独立于画质预设,可选自动跟随、原始、720p、1080p、1440p、4K 或自定义。画质预设只能在分辨率上限以内选择档位,不能覆盖用户设定的上限。
路径策略独立于画质预设:
- 智能优选:默认,并行评分 Direct/Single/Dual。
- 直连优先:直连达到最低质量门槛时不使用 CDN。
- CDN 优先:优先双边缘优质骨干,失败后回退其他路径。
高级诊断页可查看 RTT、丢包、抖动、码率、帧率、编码/解码耗时、重传和当前档位,但不允许任意修改危险的底层 RTP 参数。
## 11. 测试
在虚拟化测试网络中通过 Linux bridge/network namespace 和 `tc netem` 注入:
- 随机丢包:1%、3%、5%、10%、15%。
- 突发丢包:短突发与 Gilbert-Elliott 模型。
- RTT30、100、250、500 ms。
- 抖动:10、30、80 ms。
- 带宽阶跃:20 Mbps 降到 2 Mbps,再恢复。
- 重排、重复包和短时完全中断。
- Direct、TURN UDP、TURN TCP/TLS 和 POP 故障切换。
- Direct 可用但跨网质量差时选择 Dual Edge,并验证 POP 间骨干路径。
验收目标:
- 5% 随机丢包下会话不主动断开,输入保持可用。
- 10% 突发丢包后在数秒内降档,不持续花屏。
- 网络恢复后平稳升档,不发生持续码率振荡。
- 文件传输不会阻塞键盘、鼠标和心跳。
- 丢失关键视频参考帧后能通过 PLI/IDR 恢复。
- 日志可以区分网络、编码和解码瓶颈。
- 诊断可以区分 Direct/Relay、POP 和 TURN transport。
具体时延和画质阈值在 M0/M3 的真实机器测试后锁定,不能只凭模拟器数据决定。