7.9 KiB
全 Rust 架构迁移计划
本文是 ADR 0001 的实施计划。它描述目标和验收门槛, 不代表对应能力已经实现。实际完成度以 实现状态 为准。
迁移原则
- Agent 是服务端,Client 是原生客户端,发布运行时全部使用 Rust。
- 实时会话使用 str0m WebRTC;不自研替代 WebRTC 的媒体传输协议。
- 原始视频帧不得经过 JavaScript、WebView、Tauri IPC 或跨进程 CPU bitmap。
- 每一阶段先建立可重复测试和性能基线,再删除被替代实现。
- 迁移期间旧代码不得继续进入正式安装包或默认 CI 发布产物。
阶段 1:删除 Go/Hysteria2 构建链
状态:已完成(源码与构建链)。
工作:
- 从 Windows、Linux 和聚合打包脚本中删除 Hysteria2 构建步骤。
- 从 CI、发布清单、安装器、systemd 和环境模板中删除 Go/Hysteria2。
- 删除 transport/hysteria2-agent、go.mod、go.sum 及生成物引用。
- 移除 Go 工具链、缓存和供应链审计要求。
验收:Cargo workspace、CI 和所有安装包不调用 Go;仓库不存在被引用的 Hysteria2 二进制、服务或配置;Rust Agent 与 Client 的现有非 Hysteria2 构建仍通过。
阶段 2:新增共享 WebRTC Rust crate
状态:部分完成。共享 crate 已锁定 str0m 0.23,Windows/Linux workspace 已编译并有边界测试;macOS 目标尚未验证。
工作:
- 新增共享 webrtc crate 并锁定 str0m 版本。
- 封装 ICE、SDP、DTLS、SRTP、RTP/RTCP 和 DataChannel 事件状态机。
- 定义 socket 驱动、时钟、超时、证书指纹和会话身份接口。
- 对所有消息、候选地址、SDP 和队列设置上限。
验收:crate 在 Windows、Linux 和 macOS 目标上编译;状态机具备确定性单元测试、 畸形输入测试和超时测试;上层代码不直接依赖 str0m 内部类型。
阶段 3:Agent/Client Loopback
状态:部分完成。自动测试已覆盖 offer/answer、host ICE、DTLS/SCTP、可靠 control 与不可靠 pointer DataChannel;trickle ICE、ICE restart 和恶意网络测试尚缺。
工作:
- 在同机建立 Rust Agent 与 Rust Client 的 SDP offer/answer 交换。
- 支持 trickle ICE、候选结束、DTLS 指纹校验和 ICE restart。
- 建立可靠有序 control DataChannel。
- 建立不可靠无序 pointer DataChannel。
- 定义协议版本、消息大小、速率和权限边界。
验收:自动化测试完成 SDP、ICE、DTLS 和 DataChannel ping/pong;断开、重连、超时、 伪造指纹、乱序和超限消息均按预期失败;输入通道不被媒体测试流阻塞。
阶段 4:接入 H.264 RTP
状态:部分完成。str0m loopback 已发送和接收 H.264 access unit,现有 Agent 测试覆盖单 NAL、STAP-A、FU-A、丢包与关键帧恢复;尚缺真实网络压力测试。
工作:
- 固定 H.264 SDP profile、packetization-mode 和时钟频率。
- 实现 RFC 6184 单 NAL、STAP-A 和 FU-A 打包与重组。
- 接入 RTP 序列号、时间戳、帧边界、NACK、PLI、RTX 和关键帧恢复。
- 使用一到两帧有界队列并丢弃过期帧。
验收:录制码流可在 Agent 与 Client 间连续传输;随机和突发丢包测试可恢复; 缺片帧不呈现;关键帧丢失会请求新 IDR;媒体队列不会无界增长。
阶段 5:平台硬件编码与解码
状态:部分完成。Windows Media Foundation/D3D11 与 Linux GStreamer 硬件编码路径已有源码和自动构建;尚无三平台硬件端到端及 GPU 工具验证。
工作:
- Windows 接入 Windows Graphics Capture 或 DXGI、Media Foundation 和 D3D11/D3D12。
- Linux 接入 PipeWire、DMA-BUF 和 VA-API。
- macOS 接入 ScreenCaptureKit、VideoToolbox 和 Metal。
- 将编码器、解码器和 GPU surface 约束到可验证的 Adapter/device。
- 不提供软件编码、软件解码或 CPU bitmap 兼容回退。
验收:每个平台至少一个硬件路径完成端到端测试;运行时可证明实际硬件后端、 surface 类型和 Adapter;硬件能力不足时明确拒绝会话,不静默降级。
阶段 6:接入 wgpu 呈现
状态:部分完成。原生 Client 已使用 winit、wgpu、egui 并进入 Windows CI;解码 surface 的跨平台 GPU interop 与呈现验收尚缺。
工作:
- 使用 winit 管理窗口、显示器、DPI、全屏和输入生命周期。
- 使用 wgpu 创建高性能 Adapter、surface 和呈现管线。
- 为平台解码 surface 建立零拷贝或有证据约束的 GPU interop。
- egui 仅负责控制界面,不读取视频像素。
验收:Windows、Linux 和 macOS 均可呈现测试视频;resize、DPI、全屏、设备丢失和 显示器切换可恢复;不存在通过 JavaScript、WebView 或 CPU bitmap 的帧路径。
阶段 7:接入 Opus
状态:部分完成。共享 str0m loopback 已承载 Opus,Linux 捕获编码和 Windows 播放路径已有源码;PLC、漂移控制和真实设备验收尚缺。
工作:
- Agent 采集系统输出并编码 48 kHz Opus。
- 通过独立 RTP 音频 Track 发送并维护统一单调时钟。
- Client 使用有界 jitter buffer 解码和播放。
- 音频错误与视频、输入生命周期隔离。
验收:音频连续播放且无无界积压;丢包时使用 Opus PLC;音视频漂移受控; 音频设备切换或失败不会阻塞视频和输入。
阶段 8:接入 STUN/TURN
状态:部分完成。Edge 已签发短期 TURN 凭据,共享层校验 STUN/TURN 配置并接受外部 srflx/relay 候选;真实 NAT、TURN/UDP 和 TURN/TLS 会话尚未验收。
工作:
- 支持 host、server-reflexive 和 relay candidates。
- 接入 STUN、TURN/UDP、TURN/TCP 和 TURN/TLS 443。
- 使用短期、会话绑定的 TURN 凭据。
- 支持 ICE restart、网络切换、候选优先级和路径诊断。
验收:局域网直连、不同 NAT、公网 TURN/UDP 和受限网络 TURN/TLS 均完成测试; 客户端显示实际路径、RTT 和 relay;凭据过期、重放和跨会话使用均失败。
阶段 9:更新安装包和 CI
状态:部分完成。Windows/Linux 打包与 CI 已移除 Go、Node Web 前端、Tauri、JavaScript 清单工具和 C# 启动器构建入口;升级清单及 Windows 便携入口已迁移到 Rust,原生 Client 与安装包已加入 CI;macOS 包、升级矩阵和完整产物白名单尚缺。
工作:
- Windows、Linux 和 macOS 只打包 Rust Agent、Rust Client 和必要资源。
- CI 覆盖格式化、Clippy、测试、跨平台编译、SBOM、签名和安装验证。
- 增加 WebRTC loopback、RTP 丢包、DataChannel 和包内容测试。
- 删除 npm、Tauri、WebView2 和 Go 的发布依赖。
验收:三平台产物可安装、升级和卸载;包内容白名单通过;CI 不下载或执行 Go、 Node、Tauri CLI 或 WebView 构建工具;发布产物具备签名、校验和和 SBOM。
阶段 10:删除旧 Tauri/WebView 与兼容路径
状态:部分完成。旧 client/web、client/app-shell 及正式构建引用已删除;历史设计文档仍待归档改写,旧异步 WebRTC 驱动仍待由共享 str0m socket 驱动替换。
工作:
- 删除 client/web、Tauri app shell、React、Vite、npm lockfile 和 WebView 配置。
- 删除软件视频回退、zlib framebuffer、MSTSC fallback 和 Compatibility 策略。
- 删除旧 helper、旧协议字段、旧测试、旧打包入口和失效文档。
- 更新安全模型、用户指南、实现状态和架构图。
验收:仓库搜索不再出现生产 Tauri/WebView/Hysteria2/Go/Compatibility 入口; 所有正式功能通过 Rust 原生 Client 和 Rust Agent 完成;完整 workspace、安装包和 端到端测试通过。
完成定义
只有十个阶段全部达到验收条件,并且旧构建链不再产生发布产物,才能将全 Rust 迁移标记为完成。存在源码骨架、未运行的平台代码或仅通过 cargo check 均不算完成。