mirror of
https://github.com/mofeng-git/One-KVM.git
synced 2026-01-28 16:41:52 +08:00
- 新增 RustDesk 模块,支持与 RustDesk 客户端连接 - 实现会合服务器协议和 P2P 连接 - 支持 NaCl 加密和密钥交换 - 添加视频帧和 HID 事件适配器 - 添加 Protobuf 协议定义 (message.proto, rendezvous.proto) - 新增完整项目文档 - 各功能模块文档 (video, hid, msd, otg, webrtc 等) - hwcodec 和 RustDesk 协议技术报告 - 系统架构和技术栈文档 - 更新 Web 前端 RustDesk 配置界面和 API
68 KiB
68 KiB
One-KVM 系统架构文档
1. 项目概述
One-KVM 是一个用 Rust 编写的轻量级、开源 IP-KVM 解决方案。它提供 BIOS 级别的远程服务器管理能力,支持视频流、键鼠控制、虚拟存储、电源管理和音频等功能。
1.1 核心特性
- 单一二进制部署:Web UI + 后端一体化,无需额外配置文件
- 双流模式:支持 WebRTC(H264/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 之间共享。
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 添加新编码器
// 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 后端
// 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 添加新扩展
// 通过 ExtensionManager 管理外部进程
extension_manager.register("my-extension", ExtensionConfig {
command: "my-binary",
args: vec!["--port", "9000"],
health_check: HealthCheckConfig::Http { url: "http://localhost:9000/health" },
});