mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2026-01-28 08:31:52 +08:00
- 新增 RustDesk 模块,支持与 RustDesk 客户端连接 - 实现会合服务器协议和 P2P 连接 - 支持 NaCl 加密和密钥交换 - 添加视频帧和 HID 事件适配器 - 添加 Protobuf 协议定义 (message.proto, rendezvous.proto) - 新增完整项目文档 - 各功能模块文档 (video, hid, msd, otg, webrtc 等) - hwcodec 和 RustDesk 协议技术报告 - 系统架构和技术栈文档 - 更新 Web 前端 RustDesk 配置界面和 API
7.7 KiB
7.7 KiB
RustDesk 架构设计
系统架构图
┌──────────────────────┐
│ Rendezvous Server │
│ (hbbs) │
│ Port: 21116 │
└──────────┬───────────┘
│
┌──────────────────────────┼──────────────────────────┐
│ │ │
▼ ▼ ▼
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ Client A │ │ Client B │ │ Client C │
│ (控制端) │ │ (被控端) │ │ (被控端) │
└───────┬───────┘ └───────┬───────┘ └───────────────┘
│ │
│ P2P Connection │
│◄────────────────────────►│
│ │
│ (如果 P2P 失败) │
│ │ │
│ ▼ │
│ ┌───────────────┐ │
└─►│ Relay Server │◄──────┘
│ (hbbr) │
│ Port: 21117 │
└───────────────┘
服务器组件详解
Rendezvous Server (hbbs)
监听端口:
| 端口 | 协议 | 用途 |
|---|---|---|
| 21116 | TCP | 主要通信端口,处理 punch hole 请求 |
| 21116 | UDP | Peer 注册、NAT 类型检测 |
| 21115 | TCP | NAT 测试专用端口 |
| 21118 | WebSocket | Web 客户端支持 |
核心数据结构:
// rustdesk-server/src/rendezvous_server.rs:64-83
pub struct RendezvousServer {
tcp_punch: Arc<Mutex<HashMap<SocketAddr, Sink>>>, // TCP punch hole 连接
pm: PeerMap, // Peer 映射表
tx: Sender, // 消息发送通道
relay_servers: Arc<RelayServers>, // 可用 Relay 服务器列表
relay_servers0: Arc<RelayServers>, // 原始 Relay 服务器列表
rendezvous_servers: Arc<Vec<String>>, // Rendezvous 服务器列表
inner: Arc<Inner>, // 内部配置
}
struct Inner {
serial: i32, // 配置序列号
version: String, // 软件版本
software_url: String, // 软件更新 URL
mask: Option<Ipv4Network>, // LAN 掩码
local_ip: String, // 本地 IP
sk: Option<sign::SecretKey>, // 服务器签名密钥
}
Peer 数据结构:
// rustdesk-server/src/peer.rs:32-42
pub struct Peer {
pub socket_addr: SocketAddr, // 最后注册的地址
pub last_reg_time: Instant, // 最后注册时间
pub guid: Vec<u8>, // 数据库 GUID
pub uuid: Bytes, // 设备 UUID
pub pk: Bytes, // 公钥
pub info: PeerInfo, // Peer 信息
pub reg_pk: (u32, Instant), // 注册频率限制
}
Relay Server (hbbr)
监听端口:
| 端口 | 协议 | 用途 |
|---|---|---|
| 21117 | TCP | 主要中转端口 |
| 21119 | WebSocket | Web 客户端支持 |
核心特性:
// rustdesk-server/src/relay_server.rs:40-44
static DOWNGRADE_THRESHOLD_100: AtomicUsize = AtomicUsize::new(66); // 降级阈值
static DOWNGRADE_START_CHECK: AtomicUsize = AtomicUsize::new(1_800_000); // 检测开始时间(ms)
static LIMIT_SPEED: AtomicUsize = AtomicUsize::new(32 * 1024 * 1024); // 限速(bit/s)
static TOTAL_BANDWIDTH: AtomicUsize = AtomicUsize::new(1024 * 1024 * 1024);// 总带宽
static SINGLE_BANDWIDTH: AtomicUsize = AtomicUsize::new(128 * 1024 * 1024);// 单连接带宽
客户端架构
核心模块
rustdesk/src/
├── rendezvous_mediator.rs # Rendezvous 服务器通信
├── client.rs # 控制端核心逻辑
├── server/
│ ├── mod.rs # 被控端服务
│ ├── connection.rs # 连接处理
│ ├── video_service.rs # 视频服务
│ ├── audio_service.rs # 音频服务
│ └── input_service.rs # 输入服务
├── common.rs # 通用函数(加密、解密)
└── platform/ # 平台特定代码
RendezvousMediator
// rustdesk/src/rendezvous_mediator.rs:44-50
pub struct RendezvousMediator {
addr: TargetAddr<'static>, // 服务器地址
host: String, // 服务器主机名
host_prefix: String, // 主机前缀
keep_alive: i32, // 保活间隔
}
两种连接模式:
-
UDP 模式 (默认):
- 用于 Peer 注册和心跳
- 更低延迟
- 可能被某些防火墙阻止
-
TCP 模式:
- 用于代理环境
- WebSocket 模式
- 更可靠
连接流程概述
被控端启动流程
1. 生成设备 ID 和密钥对
2. 连接 Rendezvous Server
3. 发送 RegisterPeer 消息
4. 如果需要,发送 RegisterPk 注册公钥
5. 定期发送心跳保持在线状态
6. 等待 PunchHole 或 RequestRelay 请求
控制端连接流程
1. 输入目标设备 ID
2. 连接 Rendezvous Server
3. 发送 PunchHoleRequest 消息
4. 根据响应决定连接方式:
a. 直连 (P2P): 使用 PunchHole 信息尝试打洞
b. 局域网: 使用 LocalAddr 信息直连
c. 中转: 通过 Relay Server 连接
5. 建立安全加密通道
6. 发送 LoginRequest 进行身份验证
7. 开始远程控制会话
数据流
视频流
被控端 控制端
│ │
│ VideoFrame (H264/VP9/...) │
├─────────────────────────────────►│
│ │
│ 加密 → 传输 → 解密 → 解码 → 显示 │
输入流
控制端 被控端
│ │
│ MouseEvent/KeyEvent │
├─────────────────────────────────►│
│ │
│ 加密 → 传输 → 解密 → 模拟输入 │
高可用设计
多服务器支持
- 客户端可配置多个 Rendezvous Server
- 自动选择延迟最低的服务器
- 连接失败时自动切换备用服务器
Relay Server 选择
- 支持配置多个 Relay Server
- 轮询算法分配负载
- 定期检查 Relay Server 可用性
重连机制
// 连接超时和重试参数
const REG_INTERVAL: i64 = 12_000; // 注册间隔 12 秒
const REG_TIMEOUT: i32 = 30_000; // 注册超时 30 秒
const CONNECT_TIMEOUT: u64 = 18_000; // 连接超时 18 秒