翻到一个远程桌面开源项目 billd-desk,7.5k star,基于 Vue3 + WebRTC + Node.js + Flutter,功能对标 ToDesk / 向日葵。它最值得看的点不在功能列表,而在作者自己承认的两件事:开源版「从未发布稳定版,不建议用于生产」,以及存在两个「在现有架构下几乎不可修复」的问题——权限、控制。这两个问题恰好把 WebRTC 做远程桌面的边界划清楚了。
这篇文章按我的理解拆一下它的架构,再讲清楚为什么那两个问题修不掉,以及什么情况下你会需要这种方案。
整体架构:四端一服务
billd-desk 不是单个仓库,而是一套生态:
- billd-desk:Web 端 + Electron 桌面端(TypeScript,主仓库)
- billd-desk-server:后端,Node.js + Koa2 + Socket.io + Sequelize + MySQL + Redis
- billd-desk-admin:后台管理(设备、黑名单、远程记录)
- billd-desk-flutter:Android 移动端(Flutter 3)
中继层用 Coturn(TURN/STUN)和 SRS + FFmpeg。WebRTC 默认走 P2P,但跨公网 NAT 穿透失败时必须有 TURN 中继,Coturn 就是这个角色。SRS 在这儿更多是流媒体兜底,不是每次连接都用得上。
角色矩阵有点意思:Web 控 Windows、Web 控 Android、Windows 控 Android……组合都支持,唯独「Android 端发起控制」在开源版里还是 TODO。再对照另一条:Web 控 Web 只有「仅观看」。规律很直接——能发起控制的一端,必须有能力做系统级输入注入;做不到的平台,只能当观众。
关键链路:采集、编码、传输、回流
远程桌面本质是一条双向通道:
- 正向:被控端屏幕采集 → 编码 → 走 WebRTC 视频轨道 → 主控端解码渲染
- 反向:主控端鼠标键盘事件 → 走 DataChannel → 被控端注入系统
屏幕采集和编码是性能大头。技术栈里出现 WebCodecs + Web Worker,说明编码链路不是把 getDisplayMedia 的流当黑盒一包到底,而是拿到帧级别的控制权,才能做动态码率、动态帧率、丢帧策略这些事。编解码协议支持 H264/H265/AV1/VP8/VP9,硬件加速走 NVIDIA 的 NVENC/NVDEC,README 里写明显卡驱动需要 570.0+ 版本,实测数据到 2K + 120FPS(RTX 5070)。AMD 硬件加速明确标着未支持——自研方案里这种「只优化过一种 GPU」的取舍很常见。
输入回流走 DataChannel 而不是视频轨道。DataChannel 底层是 SCTP,默认有序可靠,可靠意味着丢包重传,重传意味着延迟。README 里网络模式分了「默认」和「低延迟」、帧率模式里有「根据画面变化智能降帧率」,这些选项本质都是在带宽和延迟之间做显式取舍,而不是让用户猜。
两个修不掉的问题:权限与控制
开源版基于 Web + Electron,问题出在这两层:
权限。浏览器和普通 Electron 应用拿不到系统级权限:UAC 提权弹窗、Ctrl+Alt+Del 安全桌面、锁屏后的界面,都截不到也点不了。远程软件要做到「无人值守」就得跨过这道墙,Web 环境过不去。这也是为什么开源版里「开机自启」「锁屏保活」标着 BUG、Pro 版才把「无人值守」列为可用。
控制。输入仿真不是发一个坐标就完事。Windows 上要调 Win32 API(SendInput / SetCursorPos 这一层),macOS 要 Cocoa 权限,Android 要 AccessibilityService 无障碍服务。Electron 主进程能做一部分,但浏览器页面里做不到系统级注入;fps 游戏里那种「使用被控端鼠标」的 raw input 模式更别想。
两个问题的根源是同一个:远程桌面的「端」必须贴近操作系统,而 Web 天生与操作系统隔离。作者说「在现有架构下几乎不可修复」不是谦虚——除非重写客户端,把原生能力(Win32 / Cocoa / AccessibilityService)接进采集和输入链路。BilldDesk Pro 就是这么干的:完全重写,修复了权限和控制,代价是 Pro 源码不再开源,改为付费订阅。
顺带一提,开源版 README 自己也写了:项目作者一人开发,初版三天写出来,后来把 master 当 dev 分支用,每次提交都可能破坏性更新——这解释了为什么很多人反馈「跑不起来、假开源」。这不是作者不厚道,而是一个人 + 破坏性迭代的仓库,本来就不是给生产用的,它是能力展示和学习样本。
什么时候该用,什么时候别用
用这套 WebRTC 方案的合理场景:
- 学习 WebRTC 全链路:信令、ICE/TURN、DataChannel、WebCodecs 帧控制,一个项目全串起来,且主体是 TypeScript,可读性在线
- 内网或自用:支持私有化部署、自定义设备码和连接密码、自定义中继服务器,小规模够用
- Web 端发起远控:ToDesk 免费版不给这个能力(要专业版才能网页发起远控)。如果你就是要「浏览器里控制一台机器」,WebRTC 是唯一现实的技术路线
别用的场景:
- 生产环境 / 无人值守 / 需要提权操作——作者自己都写了不建议
- 需要稳定更新节奏——开源版破坏性更新,commit 号即版本号
- 老系统和特殊平台——Windows 7 不支持(Electron 已放弃)、iOS 无客户端、Linux 未实测
- 想开箱即用——Docker 一键部署还在 TODO 列表里,部署要自己动手
如果你想自己搭一套,建议拿 billd-desk 当参照系而不是地基:Web 端那套采集 / 编码 / 传输思路可以直接学,但输入注入和权限层要落到原生客户端上,别指望浏览器替你解决。
项目地址:https://github.com/galaxy-s10/billd-desk