Files
One-KVM/docs/system-architecture.md
mofeng-git a8a3b6c66b feat: 添加 RustDesk 协议支持和项目文档
- 新增 RustDesk 模块,支持与 RustDesk 客户端连接
  - 实现会合服务器协议和 P2P 连接
  - 支持 NaCl 加密和密钥交换
  - 添加视频帧和 HID 事件适配器
- 添加 Protobuf 协议定义 (message.proto, rendezvous.proto)
- 新增完整项目文档
  - 各功能模块文档 (video, hid, msd, otg, webrtc 等)
  - hwcodec 和 RustDesk 协议技术报告
  - 系统架构和技术栈文档
- 更新 Web 前端 RustDesk 配置界面和 API
2025-12-31 18:59:52 +08:00

877 lines
68 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.

# One-KVM 系统架构文档
## 1. 项目概述
One-KVM 是一个用 Rust 编写的轻量级、开源 IP-KVM 解决方案。它提供 BIOS 级别的远程服务器管理能力,支持视频流、键鼠控制、虚拟存储、电源管理和音频等功能。
### 1.1 核心特性
- **单一二进制部署**Web UI + 后端一体化,无需额外配置文件
- **双流模式**:支持 WebRTCH264/H265/VP8/VP9和 MJPEG 两种流模式
- **USB OTG**:虚拟键鼠、虚拟存储、虚拟网卡
- **ATX 电源控制**GPIO/USB 继电器
- **RustDesk 协议集成**:支持跨平台访问
- **Vue3 SPA 前端**:支持中文/英文
- **SQLite 配置存储**:无需配置文件
### 1.2 目标平台
| 平台 | 架构 | 用途 |
|------|------|------|
| aarch64-unknown-linux-gnu | ARM64 | 主要目标Rockchip RK3328 等) |
| armv7-unknown-linux-gnueabihf | ARMv7 | 备选平台 |
| x86_64-unknown-linux-gnu | x86-64 | 开发/测试环境 |
---
## 2. 系统架构图
### 2.1 整体架构
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ One-KVM System │
├─────────────────────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Web Frontend (Vue3) │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ Console │ │ Settings │ │ Login │ │ Setup │ │ Virtual │ │ │
│ │ │ View │ │ View │ │ View │ │ View │ │ Keyboard │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ │
│ │ │ │ │
│ │ ┌─────────────────┴─────────────────┐ │ │
│ │ │ Pinia State Store │ │ │
│ │ └─────────────────┬─────────────────┘ │ │
│ │ │ │ │
│ │ ┌──────────────────────────────────────────────────────────────┐ │ │
│ │ │ API Client Layer │ │ │
│ │ │ HTTP REST │ WebSocket │ WebRTC Signaling │ MJPEG │ │ │
│ │ └──────────────────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ │ HTTP/WS/WebRTC │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Axum Web Server (routes.rs) │ │
│ │ ┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐ │ │
│ │ │ Public │ │ User │ │ Admin │ │ Static │ │ │
│ │ │ Routes │ │ Routes │ │ Routes │ │ Files │ │ │
│ │ └───────────┘ └───────────┘ └───────────┘ └───────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ AppState (state.rs) │ │
│ │ ┌─────────────────────────────────────────────────────────────┐ │ │
│ │ │ Central State Hub │ │ │
│ │ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ │ │
│ │ │ │ConfigStore │ │SessionStore│ │ UserStore │ │ │ │
│ │ │ │ (SQLite) │ │ (Memory) │ │ (SQLite) │ │ │ │
│ │ │ └────────────┘ └────────────┘ └────────────┘ │ │ │
│ │ │ │ │ │
│ │ │ ┌────────────┐ ┌────────────┐ ┌────────────┐ │ │ │
│ │ │ │ EventBus │ │ OtgService │ │ Extensions │ │ │ │
│ │ │ │ (Broadcast)│ │ (USB) │ │ Manager │ │ │ │
│ │ │ └────────────┘ └────────────┘ └────────────┘ │ │ │
│ │ └─────────────────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌─────────────────────────────┼─────────────────────────────┐ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ Video │ │ HID │ │ Audio │ │
│ │ Module │ │ Module │ │ Module │ │
│ ├────────────┤ ├────────────┤ ├────────────┤ │
│ │ Capture │ │ Controller │ │ Capture │ │
│ │ Encoder │ │ OTG Backend│ │ Encoder │ │
│ │ Streamer │ │ CH9329 │ │ Pipeline │ │
│ │ Pipeline │ │ DataChannel│ │ (Opus) │ │
│ └────────────┘ └────────────┘ └────────────┘ │
│ │ │ │ │
│ └───────────────────────────┼──────────────────────────┘ │
│ │ │
│ ┌─────────────────────────────┼─────────────────────────────┐ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ MSD │ │ ATX │ │ RustDesk │ │
│ │ Module │ │ Module │ │ Module │ │
│ ├────────────┤ ├────────────┤ ├────────────┤ │
│ │ Controller │ │ Controller │ │ Service │ │
│ │ Image Mgr │ │ Executor │ │ Rendezvous │ │
│ │ Ventoy │ │ LED Monitor│ │ Connection │ │
│ │ Drive │ │ WOL │ │ Protocol │ │
│ └────────────┘ └────────────┘ └────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────┐
│ Hardware Layer │
├─────────────────────────────────────────────────────────────────────────────┤
│ ┌────────────┐ ┌────────────┐ ┌────────────┐ ┌────────────┐ │
│ │ V4L2 Video │ │ USB OTG │ │ GPIO │ │ ALSA │ │
│ │ Device │ │ Gadget │ │ Sysfs │ │ Audio │ │
│ │/dev/video* │ │ ConfigFS │ │ │ │ │ │
│ └────────────┘ └────────────┘ └────────────┘ └────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
```
### 2.2 数据流架构
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ Data Flow Overview │
└─────────────────────────────────────────────────────────────────────────────┘
┌─────────────────┐
│ Target PC │
└────────┬────────┘
┌────────────────────────┼────────────────────────┐
│ │ │
▼ ▼ ▼
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ HDMI Capture │ │ USB Port │ │ GPIO/Relay │
│ Card │ │ (OTG Mode) │ │ (ATX) │
└───────┬───────┘ └───────┬───────┘ └───────┬───────┘
│ │ │
▼ ▼ ▼
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ /dev/video0 │ │ /dev/hidg* │ │ /sys/class/ │
│ (V4L2) │ │ (USB Gadget) │ │ gpio/gpio* │
└───────┬───────┘ └───────┬───────┘ └───────┬───────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────────────┐
│ One-KVM Application │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Video │ │ HID │ │ ATX │ │
│ │ Pipeline │ │ Controller │ │ Controller │ │
│ └─────┬───────┘ └─────┬───────┘ └─────┬───────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌───────────────────────────────────────────────────────┐ │
│ │ Event Bus │ │
│ │ (tokio broadcast channel) │ │
│ └───────────────────────────────────────────────────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Web Server (Axum) │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │
│ │ │ MJPEG │ │ WebRTC │ │WebSocket │ │ │
│ │ │ Stream │ │ Stream │ │ Events │ │ │
│ │ └──────────┘ └──────────┘ └──────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────────────────────────┐
│ Client Browser │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Video │ │ Input │ │ Control │ │
│ │ Display │ │ Events │ │ Panel │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
└─────────────────────────────────────────────────────────────┘
```
---
## 3. 模块依赖关系
### 3.1 模块层次图
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ Application Layer │
├─────────────────────────────────────────────────────────────────────────────┤
│ main.rs ──► state.rs ──► web/routes.rs │
│ │ │
│ ┌───────────┼───────────┬───────────┬───────────┬───────────┐ │
│ │ │ │ │ │ │ │
│ ▼ ▼ ▼ ▼ ▼ ▼ │
│ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ ┌──────┐ │
│ │video/│ │ hid/ │ │ msd/ │ │ atx/ │ │audio/│ │webrtc│ │
│ └──┬───┘ └──┬───┘ └──┬───┘ └──┬───┘ └──┬───┘ └──┬───┘ │
│ │ │ │ │ │ │ │
│ │ └──────────┼──────────┘ │ │ │
│ │ │ │ │ │
│ │ ┌─────▼─────┐ │ │ │
│ │ │ otg/ │ │ │ │
│ │ │ (OtgSvc) │ │ │ │
│ │ └───────────┘ │ │ │
│ │ │ │ │
│ └──────────────────────────────────────────┼──────────┘ │
│ │ │
├─────────────────────────────────────────────────────────────────────────────┤
│ Infrastructure Layer │
├─────────────────────────────────────────────────────────────────────────────┤
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ config/ │ │ auth/ │ │ events/ │ │extensions│ │
│ │(ConfigSt)│ │(Session) │ │(EventBus)│ │(ExtMgr) │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
│ │
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ rustdesk/ (RustDeskService) │ │
│ │ connection.rs │ rendezvous.rs │ crypto.rs │ protocol.rs │ │
│ └───────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
```
### 3.2 依赖矩阵
| 模块 | 依赖的模块 |
|------|-----------|
| `main.rs` | state, config, auth, video, hid, msd, atx, audio, webrtc, web, rustdesk, events |
| `state.rs` | config, auth, video, hid, msd, atx, audio, webrtc, rustdesk, events, otg |
| `video/` | events, hwcodec (外部) |
| `hid/` | otg, events |
| `msd/` | otg, events |
| `atx/` | events |
| `audio/` | events |
| `webrtc/` | video, audio, hid, events |
| `web/` | state, auth, config, video, hid, msd, atx, audio, webrtc, events |
| `rustdesk/` | video, audio, hid, events |
| `otg/` | (无内部依赖) |
| `config/` | (无内部依赖) |
| `auth/` | config |
| `events/` | (无内部依赖) |
---
## 4. 核心组件详解
### 4.1 AppState (state.rs)
AppState 是整个应用的状态中枢,通过 `Arc` 包装的方式在所有 handler 之间共享。
```rust
pub struct AppState {
// 配置和存储
config: ConfigStore, // SQLite 配置存储
sessions: SessionStore, // 内存会话存储
users: UserStore, // SQLite 用户存储
// 核心服务
otg_service: Arc<OtgService>, // USB Gadget 统一管理
stream_manager: Arc<VideoStreamManager>, // 视频流管理器
hid: Arc<HidController>, // HID 控制器
msd: Arc<RwLock<Option<MsdController>>>, // MSD 控制器(可选)
atx: Arc<RwLock<Option<AtxController>>>, // ATX 控制器(可选)
audio: Arc<AudioController>, // 音频控制器
rustdesk: Arc<RwLock<Option<Arc<RustDeskService>>>>, // RustDesk可选
extensions: Arc<ExtensionManager>,// 扩展管理器
// 通信和生命周期
events: Arc<EventBus>, // 事件总线
shutdown_tx: broadcast::Sender<()>, // 关闭信号
data_dir: PathBuf, // 数据目录
}
```
### 4.2 视频流管道
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ Video Pipeline Architecture │
└─────────────────────────────────────────────────────────────────────────────┘
┌───────────────────┐
│ V4L2 Device │
│ /dev/video0 │
└─────────┬─────────┘
│ Raw MJPEG/YUYV/NV12
┌───────────────────┐
│ VideoCapturer │ ◄─── src/video/capture.rs
│ (capture.rs) │
└─────────┬─────────┘
│ VideoFrame
┌───────────────────────────────────────────────────────────────────────────┐
│ SharedVideoPipeline │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Decode Stage │ │
│ │ ┌─────────────┐ │ │
│ │ │ MJPEG → YUV │ turbojpeg / VAAPI │ │
│ │ └─────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Convert Stage │ │
│ │ ┌─────────────┐ │ │
│ │ │YUV → Target │ libyuv (SIMD accelerated) │ │
│ │ │ Format │ │ │
│ │ └─────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Encode Stage │ │
│ │ ┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐ │ │
│ │ │ H264 │ │ H265 │ │ VP8 │ │ VP9 │ │ │
│ │ │Encoder │ │Encoder │ │Encoder │ │Encoder │ │ │
│ │ └────────┘ └────────┘ └────────┘ └────────┘ │ │
│ │ │ (VAAPI/RKMPP/V4L2 M2M/Software) │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────────────────────┘
├──────────────────────────────────────────┐
│ │
▼ ▼
┌───────────────────┐ ┌───────────────────┐
│ MJPEG Streamer │ │ WebRTC Streamer │
│ (HTTP Stream) │ │ (RTP Packets) │
└───────────────────┘ └───────────────────┘
```
### 4.3 OTG 服务架构
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ OTG Service Architecture │
└─────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────┐
│ OtgService (service.rs) │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Public Interface │ │
│ │ enable_hid() │ disable_hid() │ enable_msd() │ disable_msd() │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ OtgGadgetManager (manager.rs) │ │
│ │ ┌───────────────────────────────────────────────────────────────┐ │ │
│ │ │ Gadget Lifecycle │ │ │
│ │ │ create_gadget() │ destroy_gadget() │ bind_udc() │ unbind() │ │ │
│ │ └───────────────────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌────────────────────────┼────────────────────────┐ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │
│ │ HID Function │ │ MSD Function │ │ Endpoint Alloc │ │
│ │ (hid.rs) │ │ (msd.rs) │ │ (endpoint.rs) │ │
│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │
│ │ │ │
│ ▼ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ ConfigFS Operations │ │
│ │ /sys/kernel/config/usb_gadget/one-kvm/ │ │
│ │ ├── idVendor, idProduct, strings/ │ │
│ │ ├── configs/c.1/ │ │
│ │ │ └── functions/ (symlinks) │ │
│ │ └── functions/ │ │
│ │ ├── hid.usb0, hid.usb1, hid.usb2 │ │
│ │ └── mass_storage.usb0 │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────┐
│ Linux Kernel │
│ ┌─────────────────┐ ┌─────────────────┐ │
│ │ /dev/hidg* │ │ Mass Storage │ │
│ │ (HID devices) │ │ Backend │ │
│ └─────────────────┘ └─────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
```
### 4.4 事件系统架构
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ Event System Architecture │
└─────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────┐
│ Event Producers │
├─────────────────────────────────────────────────────────────────────────────┤
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Video │ │ HID │ │ MSD │ │ ATX │ │ Audio │ │
│ │ Module │ │ Module │ │ Module │ │ Module │ │ Module │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
│ │ │ │ │ │ │
│ └────────────┴────────────┼────────────┴────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ EventBus │ │
│ │ (tokio broadcast channel) │ │
│ │ ┌───────────────────────────────────────────────────────────────┐ │ │
│ │ │ SystemEvent Enum │ │ │
│ │ │ StreamStateChanged │ HidStateChanged │ MsdStateChanged │ │ │
│ │ │ AtxStateChanged │ AudioStateChanged │ DeviceInfo │ Error │ │ │
│ │ └───────────────────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │ │
│ ┌─────────────────────────┼─────────────────────────┐ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │WebSocket │ │ DeviceInfo│ │ Internal │ │
│ │ Clients │ │Broadcaster│ │ Tasks │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘
```
---
## 5. 初始化流程
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ Application Startup Flow │
└─────────────────────────────────────────────────────────────────────────────┘
main()
├──► Parse CLI Arguments (clap)
│ - address, port, data_dir
│ - enable_https, ssl_cert, ssl_key
│ - verbosity (-v, -vv, -vvv)
├──► Initialize Logging (tracing)
├──► Create/Open SQLite Database
│ └─► ConfigStore::new()
│ └─► UserStore::new()
│ └─► SessionStore::new()
├──► Initialize Core Services
│ │
│ ├──► EventBus::new()
│ │
│ ├──► OtgService::new()
│ │ └─► Detect UDC device
│ │
│ ├──► HidController::init()
│ │ └─► Select backend (OTG/CH9329/None)
│ │ └─► Request HID function from OtgService
│ │
│ ├──► MsdController::init() (if configured)
│ │ └─► Request MSD function from OtgService
│ │ └─► Initialize Ventoy drive (if available)
│ │
│ ├──► AtxController::init() (if configured)
│ │ └─► Setup GPIO pins
│ │
│ ├──► AudioController::init()
│ │ └─► Open ALSA device
│ │ └─► Initialize Opus encoder
│ │
│ ├──► VideoStreamManager::new()
│ │ └─► Initialize SharedVideoPipeline
│ │ └─► Setup encoder registry
│ │
│ └──► RustDeskService::new() (if configured)
│ └─► Load/generate device ID and keys
│ └─► Connect to rendezvous server
├──► Create AppState
│ └─► Wrap all services in Arc<>
├──► Spawn Background Tasks
│ ├──► spawn_device_info_broadcaster()
│ ├──► extension_health_check_task()
│ └──► rustdesk_reconnect_task()
├──► Create Axum Router
│ └─► create_router(app_state)
└──► Start HTTP/HTTPS Server
└─► axum::serve() or axum_server with TLS
```
---
## 6. 目录结构
```
One-KVM-RUST/
├── src/ # Rust 源代码
│ ├── main.rs # 应用入口点
│ ├── lib.rs # 库导出
│ ├── state.rs # AppState 定义
│ ├── error.rs # 错误类型定义
│ │
│ ├── video/ # 视频模块
│ │ ├── mod.rs
│ │ ├── capture.rs # V4L2 采集
│ │ ├── streamer.rs # 视频流服务
│ │ ├── stream_manager.rs # 流管理器
│ │ ├── shared_video_pipeline.rs # 共享视频管道
│ │ ├── format.rs # 像素格式
│ │ ├── frame.rs # 视频帧
│ │ ├── convert.rs # 格式转换
│ │ └── encoder/ # 编码器
│ │ ├── mod.rs
│ │ ├── traits.rs
│ │ ├── h264.rs
│ │ ├── h265.rs
│ │ ├── vp8.rs
│ │ ├── vp9.rs
│ │ └── jpeg.rs
│ │
│ ├── hid/ # HID 模块
│ │ ├── mod.rs # HidController
│ │ ├── backend.rs # 后端抽象
│ │ ├── otg.rs # OTG 后端
│ │ ├── ch9329.rs # CH9329 串口后端
│ │ ├── keymap.rs # 按键映射
│ │ ├── types.rs # 类型定义
│ │ ├── monitor.rs # 健康监视
│ │ ├── datachannel.rs # DataChannel 适配
│ │ └── websocket.rs # WebSocket 适配
│ │
│ ├── otg/ # USB OTG 模块
│ │ ├── mod.rs
│ │ ├── service.rs # OtgService
│ │ ├── manager.rs # GadgetManager
│ │ ├── hid.rs # HID Function
│ │ ├── msd.rs # MSD Function
│ │ ├── configfs.rs # ConfigFS 操作
│ │ ├── endpoint.rs # 端点分配
│ │ └── report_desc.rs # HID 报告描述符
│ │
│ ├── msd/ # MSD 模块
│ │ ├── mod.rs
│ │ ├── controller.rs # MsdController
│ │ ├── image.rs # 镜像管理
│ │ ├── ventoy_drive.rs # Ventoy 驱动
│ │ ├── monitor.rs # 健康监视
│ │ └── types.rs # 类型定义
│ │
│ ├── atx/ # ATX 模块
│ │ ├── mod.rs
│ │ ├── controller.rs # AtxController
│ │ ├── executor.rs # 动作执行器
│ │ ├── types.rs # 类型定义
│ │ ├── led.rs # LED 监视
│ │ └── wol.rs # Wake-on-LAN
│ │
│ ├── audio/ # 音频模块
│ │ ├── mod.rs
│ │ ├── controller.rs # AudioController
│ │ ├── capture.rs # ALSA 采集
│ │ ├── encoder.rs # Opus 编码
│ │ ├── shared_pipeline.rs # 共享管道
│ │ ├── monitor.rs # 健康监视
│ │ └── device.rs # 设备枚举
│ │
│ ├── webrtc/ # WebRTC 模块
│ │ ├── mod.rs
│ │ ├── webrtc_streamer.rs # WebRTC 管理器
│ │ ├── universal_session.rs # 会话管理
│ │ ├── video_track.rs # 视频轨道
│ │ ├── rtp.rs # RTP 打包
│ │ ├── h265_payloader.rs # H265 RTP
│ │ ├── peer.rs # PeerConnection
│ │ ├── config.rs # 配置
│ │ ├── signaling.rs # 信令
│ │ └── track.rs # 轨道基类
│ │
│ ├── auth/ # 认证模块
│ │ ├── mod.rs
│ │ ├── user.rs # 用户管理
│ │ ├── session.rs # 会话管理
│ │ ├── password.rs # 密码哈希
│ │ └── middleware.rs # Axum 中间件
│ │
│ ├── config/ # 配置模块
│ │ ├── mod.rs
│ │ ├── schema.rs # 配置结构定义
│ │ └── store.rs # SQLite 存储
│ │
│ ├── events/ # 事件模块
│ │ └── mod.rs # EventBus
│ │
│ ├── rustdesk/ # RustDesk 模块
│ │ ├── mod.rs # RustDeskService
│ │ ├── connection.rs # 连接管理
│ │ ├── rendezvous.rs # 渲染服务器通信
│ │ ├── crypto.rs # NaCl 加密
│ │ ├── config.rs # 配置
│ │ ├── hid_adapter.rs # HID 适配
│ │ ├── frame_adapters.rs # 帧格式转换
│ │ ├── protocol.rs # 协议包装
│ │ └── bytes_codec.rs # 帧编码
│ │
│ ├── extensions/ # 扩展模块
│ │ └── mod.rs # ExtensionManager
│ │
│ ├── web/ # Web 模块
│ │ ├── mod.rs
│ │ ├── routes.rs # 路由定义
│ │ ├── ws.rs # WebSocket
│ │ ├── audio_ws.rs # 音频 WebSocket
│ │ ├── static_files.rs # 静态文件
│ │ └── handlers/ # API 处理器
│ │ ├── mod.rs
│ │ └── config/
│ │
│ ├── stream/ # MJPEG 流
│ │ └── mod.rs
│ │
│ └── utils/ # 工具函数
│ └── mod.rs
├── web/ # Vue3 前端
│ ├── src/
│ │ ├── views/ # 页面组件
│ │ ├── components/ # UI 组件
│ │ ├── api/ # API 客户端
│ │ ├── stores/ # Pinia 状态
│ │ ├── router/ # 路由配置
│ │ ├── i18n/ # 国际化
│ │ └── types/ # TypeScript 类型
│ └── package.json
├── libs/ # 外部库
│ ├── hwcodec/ # 硬件视频编码
│ └── ventoy-img-rs/ # Ventoy 支持
├── protos/ # Protobuf 定义
│ ├── message.proto # RustDesk 消息
│ └── rendezvous.proto # RustDesk 渲染
├── docs/ # 文档
├── scripts/ # 脚本
├── Cargo.toml # Rust 配置
├── build.rs # 构建脚本
└── README.md
```
---
## 7. 安全架构
### 7.1 认证流程
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ Authentication Flow │
└─────────────────────────────────────────────────────────────────────────────┘
┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐
│ Client │ │ Axum │ │ Auth │ │ SQLite │
│ Browser │ │ Server │ │ Module │ │ Database │
└─────┬─────┘ └─────┬─────┘ └─────┬─────┘ └─────┬─────┘
│ │ │ │
│ POST /auth/login │ │ │
│ {username, pass} │ │ │
│───────────────────►│ │ │
│ │ verify_user() │ │
│ │───────────────────►│ │
│ │ │ SELECT user │
│ │ │───────────────────►│
│ │ │◄───────────────────│
│ │ │ │
│ │ │ Argon2 verify │
│ │ │ ────────────► │
│ │ │ │
│ │ session_token │ │
│ │◄───────────────────│ │
│ │ │ │
│ Set-Cookie: │ │ │
│ session_id=token │ │ │
│◄───────────────────│ │ │
│ │ │ │
│ GET /api/... │ │ │
│ Cookie: session │ │ │
│───────────────────►│ │ │
│ │ validate_session()│ │
│ │───────────────────►│ │
│ │ user_info │ │
│ │◄───────────────────│ │
│ │ │ │
│ Response │ │ │
│◄───────────────────│ │ │
```
### 7.2 权限层级
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ Permission Levels │
└─────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────┐
│ Public (No Auth) │
│ ├── GET /health │
│ ├── POST /auth/login │
│ ├── GET /setup │
│ └── POST /setup/init │
├─────────────────────────────────────────────────────────────────────────────┤
│ User (Authenticated) │
│ ├── GET /info (系统信息) │
│ ├── GET /devices (设备列表) │
│ ├── GET/POST /stream/* (流控制) │
│ ├── POST /webrtc/* (WebRTC 信令) │
│ ├── POST /hid/* (HID 控制) │
│ ├── POST /audio/* (音频控制) │
│ └── WebSocket endpoints (实时通信) │
├─────────────────────────────────────────────────────────────────────────────┤
│ Admin (Admin Role) │
│ ├── GET/PATCH /config/* (配置管理) │
│ ├── POST /msd/* (MSD 操作) │
│ ├── POST /atx/* (电源控制) │
│ ├── POST /extensions/* (扩展管理) │
│ ├── POST /rustdesk/* (RustDesk 配置) │
│ └── POST /users/* (用户管理) │
└─────────────────────────────────────────────────────────────────────────────┘
```
---
## 8. 部署架构
### 8.1 单机部署
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ Single Binary Deployment │
└─────────────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────────────┐
│ ARM64 Device (e.g., Rockchip RK3328) │
│ ┌───────────────────────────────────────────────────────────────────────┐ │
│ │ one-kvm (single binary, ~15MB) │ │
│ │ ┌─────────────────────────────────────────────────────────────────┐ │ │
│ │ │ Embedded Assets (rust-embed, gzip compressed) │ │ │
│ │ │ - index.html, app.js, app.css, assets/* │ │ │
│ │ └─────────────────────────────────────────────────────────────────┘ │ │
│ │ ┌─────────────────────────────────────────────────────────────────┐ │ │
│ │ │ Runtime Data (data_dir) │ │ │
│ │ │ - one-kvm.db (SQLite) │ │ │
│ │ │ - images/ (MSD images) │ │ │
│ │ │ - certs/ (SSL certificates) │ │ │
│ │ └─────────────────────────────────────────────────────────────────┘ │ │
│ └───────────────────────────────────────────────────────────────────────┘ │
│ │
│ Hardware Connections: │
│ ┌───────────────────┐ ┌───────────────────┐ ┌───────────────────┐ │
│ │ HDMI Input │ │ USB OTG Port │ │ GPIO Header │ │
│ │ (/dev/video0) │ │ (USB Gadget) │ │ (ATX Control) │ │
│ └───────────────────┘ └───────────────────┘ └───────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
│ USB Cable
┌─────────────────────────────────────────────────────────────────────────────┐
│ Target PC │
│ - Receives USB HID events (keyboard/mouse) │
│ - Provides HDMI video output │
│ - Can boot from virtual USB drive │
└─────────────────────────────────────────────────────────────────────────────┘
```
### 8.2 网络拓扑
```
┌─────────────────────────────────────────────────────────────────────────────┐
│ Network Topology │
└─────────────────────────────────────────────────────────────────────────────┘
Internet
┌───────────┴───────────┐
│ │
▼ ▼
┌───────────────┐ ┌───────────────┐
│ RustDesk │ │ Client │
│ Server │ │ Browser │
│ (hbbs/hbbr) │ │ │
└───────────────┘ └───────────────┘
│ │
│ │
└───────────┬───────────┘
┌────┴────┐
│ Router │
│ NAT │
└────┬────┘
Local Network
┌───────────┴───────────┐
│ │
▼ ▼
┌───────────────┐ ┌───────────────┐
│ One-KVM │───────│ Target PC │
│ Device │ USB │ │
│ :8080/:8443 │ HID │ │
└───────────────┘ └───────────────┘
Access Methods:
1. Local: http://one-kvm.local:8080
2. HTTPS: https://one-kvm.local:8443
3. RustDesk: Via RustDesk client with device ID
```
---
## 9. 扩展点
### 9.1 添加新编码器
```rust
// 1. 实现 Encoder trait
impl Encoder for MyEncoder {
fn encode(&mut self, frame: &VideoFrame) -> Result<Vec<u8>>;
fn codec(&self) -> Codec;
fn bitrate(&self) -> u32;
// ...
}
// 2. 在 registry 中注册
encoder_registry.register("my-encoder", || Box::new(MyEncoder::new()));
```
### 9.2 添加新 HID 后端
```rust
// 1. 实现 HidBackend trait
impl HidBackend for MyBackend {
async fn send_keyboard(&self, event: &KeyboardEvent) -> Result<()>;
async fn send_mouse(&self, event: &MouseEvent) -> Result<()>;
fn info(&self) -> HidBackendInfo;
// ...
}
// 2. 在 HidController::init() 中添加分支
match config.backend {
HidBackendType::MyBackend => MyBackend::new(config),
// ...
}
```
### 9.3 添加新扩展
```rust
// 通过 ExtensionManager 管理外部进程
extension_manager.register("my-extension", ExtensionConfig {
command: "my-binary",
args: vec!["--port", "9000"],
health_check: HealthCheckConfig::Http { url: "http://localhost:9000/health" },
});
```
---
## 10. 参考资料
- [Axum Web Framework](https://github.com/tokio-rs/axum)
- [webrtc-rs](https://github.com/webrtc-rs/webrtc)
- [V4L2 Documentation](https://www.kernel.org/doc/html/latest/userspace-api/media/v4l/v4l2.html)
- [Linux USB Gadget](https://www.kernel.org/doc/html/latest/usb/gadget_configfs.html)
- [RustDesk Protocol](https://github.com/rustdesk/rustdesk)