Files
RemoteDesk/docs/network-adaptation.md
曾志威 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

11 KiB
Raw Permalink Blame History

RemoteDesk 差网络自适应设计

1. 目标

RemoteDesk 在延迟、抖动、随机丢包和突发丢包变化时保持会话可控制。优先级固定为:

键盘/鼠标按键 > 控制与心跳 > 音频 > 视频实时性 > 视频清晰度 > 剪贴板 > 文件传输

目标不是在任意丢包率下维持最高画质,而是在恶化时快速退化、避免断开,在恢复时平稳升档。

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. 分辨率:码率不足时按档位降采样,不频繁重建会话。

建议的初始阶梯:

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. 重连

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 的真实机器测试后锁定,不能只凭模拟器数据决定。