Files
One-KVM/docs/tech-stack.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

19 KiB

One-KVM 技术栈文档

1. 概述

One-KVM 采用现代化的 Rust + Vue3 技术栈,追求高性能、低资源占用和类型安全。本文档详细介绍项目使用的技术、库和开发规范。


2. 后端技术栈

2.1 核心语言和运行时

技术 版本 用途
Rust Edition 2021 主要开发语言
Tokio 1.x 异步运行时

Rust 特性使用

// Edition 2021 特性
- async/await 异步编程
- 模式匹配 (match, if let)
- 错误处理 (Result, ?)
- 智能指针 (Arc, Mutex, RwLock)
- trait 系统
- 生命周期
- 泛型

2.2 Web 框架

版本 用途
axum 0.7 Web 框架
axum-extra 0.9 Cookie、TypedHeader 支持
tower-http 0.5 CORS、压缩、追踪中间件
axum-server 0.7 TLS/HTTPS 服务器

Axum 使用模式

// 路由定义
Router::new()
    .route("/api/stream/start", post(handlers::stream_start))
    .route("/api/stream/stop", post(handlers::stream_stop))
    .with_state(app_state)

// 处理器函数
async fn stream_start(
    State(state): State<Arc<AppState>>,
    Json(payload): Json<StreamStartRequest>,
) -> Result<Json<StreamResponse>, AppError>

// 中间件
.layer(CorsLayer::permissive())
.layer(CompressionLayer::new())
.layer(TraceLayer::new_for_http())

2.3 数据库

版本 用途
SQLx 0.8 异步 SQL 工具包
SQLite (bundled) 嵌入式数据库

数据库设计

-- 配置表 (JSON blob 存储)
CREATE TABLE IF NOT EXISTS config (
    key TEXT PRIMARY KEY,
    value TEXT NOT NULL,
    updated_at TEXT NOT NULL
);

-- 用户表
CREATE TABLE IF NOT EXISTS users (
    id TEXT PRIMARY KEY,
    username TEXT UNIQUE NOT NULL,
    password_hash TEXT NOT NULL,
    role TEXT NOT NULL,
    created_at TEXT NOT NULL
);

2.4 序列化

版本 用途
serde 1.x 序列化框架
serde_json 1.x JSON 序列化
prost 0.13 Protobuf 序列化 (RustDesk)

2.5 日志和追踪

版本 用途
tracing 0.1 结构化日志
tracing-subscriber 0.3 日志订阅器

日志级别

-v      # WARN + INFO
-vv     # + DEBUG
-vvv    # + TRACE

2.6 错误处理

版本 用途
thiserror 1.x 错误类型派生
anyhow 1.x 通用错误处理

错误处理模式

#[derive(Debug, thiserror::Error)]
pub enum AppError {
    #[error("Authentication failed")]
    AuthError,

    #[error("Resource not found: {0}")]
    NotFound(String),

    #[error("Internal error: {0}")]
    Internal(#[from] anyhow::Error),
}

impl IntoResponse for AppError {
    fn into_response(self) -> Response {
        let (status, message) = match self {
            AppError::AuthError => (StatusCode::UNAUTHORIZED, self.to_string()),
            AppError::NotFound(_) => (StatusCode::NOT_FOUND, self.to_string()),
            AppError::Internal(_) => (StatusCode::INTERNAL_SERVER_ERROR, "Internal error".into()),
        };
        (status, Json(json!({ "error": message }))).into_response()
    }
}

2.7 认证和安全

版本 用途
argon2 0.5 密码哈希
rand 0.8 随机数生成
rustls 0.23 TLS 实现
rcgen 0.13 证书生成
sodiumoxide 0.2 NaCl 加密 (RustDesk)
sha2 0.10 SHA-256 哈希

密码哈希

use argon2::{Argon2, PasswordHasher, PasswordVerifier};

// 哈希密码
let salt = SaltString::generate(&mut OsRng);
let hash = Argon2::default()
    .hash_password(password.as_bytes(), &salt)?
    .to_string();

// 验证密码
Argon2::default()
    .verify_password(password.as_bytes(), &parsed_hash)?;

2.8 视频处理

版本 用途
v4l 0.14 V4L2 视频采集
turbojpeg 1.1 JPEG 编码 (SIMD)
hwcodec (vendored) 硬件视频编码
libyuv (vendored) YUV 格式转换

视频编码优先级

1. VAAPI (Intel/AMD GPU)
2. RKMPP (Rockchip)
3. V4L2 M2M (通用硬件)
4. Software (libx264/libvpx)

支持的像素格式

pub enum PixelFormat {
    // 压缩格式 (优先)
    Mjpeg,      // Motion JPEG
    Jpeg,       // Static JPEG

    // YUV 4:2:2 打包格式
    Yuyv,       // YUYV (最常见)
    Yvyu,       // YVYU
    Uyvy,       // UYVY

    // YUV 半平面格式
    Nv12,       // NV12 (常见)
    Nv16,       // NV16
    Nv24,       // NV24

    // YUV 平面格式
    Yuv420,     // I420/YU12
    Yvu420,     // YV12

    // RGB 格式
    Rgb565,     // RGB565
    Rgb24,      // RGB24
    Bgr24,      // BGR24

    // 灰度
    Grey,       // 8-bit grayscale
}

2.9 音频处理

版本 用途
alsa 0.9 ALSA 音频采集
audiopus 0.2 Opus 编码

音频配置

// 采样参数
const SAMPLE_RATE: u32 = 48000;
const CHANNELS: u16 = 2;
const FRAME_SIZE: usize = 960;  // 20ms at 48kHz

// 质量配置
pub enum AudioQuality {
    VeryLow,   // 24 kbps
    Low,       // 48 kbps
    Medium,    // 64 kbps
    High,      // 96 kbps
}

2.10 WebRTC

版本 用途
webrtc 0.14 WebRTC 实现
rtp 0.14 RTP 协议

WebRTC 配置

// ICE 服务器配置
pub struct IceServerConfig {
    pub stun_servers: Vec<String>,   // STUN 服务器
    pub turn_servers: Vec<TurnServer>, // TURN 服务器
}

// 默认 STUN
"stun:stun.l.google.com:19302"

2.11 硬件交互

版本 用途
nix 0.29 Unix 系统调用
gpio-cdev 0.6 GPIO 控制
serialport 4.x 串口通信
libc 0.2 C 库绑定

GPIO 操作

// 使用 gpio-cdev
let chip = Chip::new("/dev/gpiochip0")?;
let line = chip.get_line(pin)?;
let handle = line.request(LineRequestFlags::OUTPUT, 0, "one-kvm")?;
handle.set_value(1)?;  // 设置高电平

串口通信 (CH9329)

// 打开串口
let port = serialport::new(device, baud_rate)
    .timeout(Duration::from_millis(100))
    .open()?;

// 发送 HID 报告
port.write(&hid_report)?;

2.12 并发同步

版本 用途
parking_lot 0.12 高性能锁
arc-swap 1.7 原子引用交换
tokio 1.x 异步通道

同步模式

// 共享状态
Arc<RwLock<T>>           // 读多写少
Arc<Mutex<T>>            // 互斥访问
Arc<AtomicU64>           // 原子操作

// 通道
tokio::sync::broadcast   // 多生产者多消费者
tokio::sync::mpsc        // 多生产者单消费者
tokio::sync::oneshot     // 一次性通知

2.13 网络和 HTTP

版本 用途
reqwest 0.12 HTTP 客户端
tokio-tungstenite 0.24 WebSocket 客户端
urlencoding 2.x URL 编码

2.14 工具库

版本 用途
uuid 1.x UUID 生成
chrono 0.4 时间处理
base64 0.22 Base64 编码
bytes 1.x 字节缓冲区
bytemuck 1.14 零拷贝类型转换
xxhash-rust 0.8 快速哈希
futures 0.3 Future 工具
async-trait 0.1 异步 trait

2.15 静态资源嵌入

版本 用途
rust-embed 8.x 资源嵌入
mime_guess 2.x MIME 类型推断

资源嵌入模式

#[derive(RustEmbed)]
#[folder = "web/dist"]
#[include = "*.html"]
#[include = "*.js"]
#[include = "*.css"]
#[include = "assets/*"]
struct Assets;

// Debug: 从文件系统读取
// Release: 嵌入二进制 (gzip 压缩)

2.16 CLI

版本 用途
clap 4.x 命令行解析

CLI 参数

#[derive(Parser)]
struct Args {
    #[arg(short, long, default_value = "0.0.0.0")]
    address: String,

    #[arg(short, long, default_value = "8080")]
    port: u16,

    #[arg(short, long)]
    data_dir: Option<PathBuf>,

    #[arg(long)]
    enable_https: bool,

    #[arg(short, long, action = clap::ArgAction::Count)]
    verbose: u8,
}

2.17 类型生成

版本 用途
typeshare 1.0 TypeScript 类型生成

类型共享

#[derive(Serialize, Deserialize)]
#[typeshare]
pub struct VideoConfig {
    pub device: Option<String>,
    pub width: u32,
    pub height: u32,
    pub fps: u32,
}

// 生成 TypeScript:
// export interface VideoConfig {
//     device?: string;
//     width: number;
//     height: number;
//     fps: number;
// }

3. 前端技术栈

3.1 核心框架

技术 版本 用途
Vue 3 3.5.x UI 框架
Vue Router 4.6.x 路由
Pinia 3.0.x 状态管理
TypeScript 5.9.x 类型系统

Vue 3 组合式 API

<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { useSystemStore } from '@/stores/system'

const store = useSystemStore()
const streaming = computed(() => store.streamState === 'streaming')

onMounted(async () => {
  await store.fetchDeviceInfo()
})
</script>

3.2 UI 组件库

版本 用途
Radix Vue 1.9.x 无头 UI 组件
Reka UI 2.6.x UI 组件
shadcn-vue - 组件样式
Lucide Vue 0.556.x 图标库

3.3 样式

技术 版本 用途
Tailwind CSS 4.1.x 原子化 CSS
tailwind-merge 3.4.x 类名合并
class-variance-authority 0.7.x 变体管理
tw-animate-css 1.4.x 动画

Tailwind 配置

// tailwind.config.js
export default {
  darkMode: 'class',
  content: ['./src/**/*.{vue,ts}'],
  theme: {
    extend: {
      colors: {
        border: 'hsl(var(--border))',
        background: 'hsl(var(--background))',
        foreground: 'hsl(var(--foreground))',
      },
    },
  },
}

3.4 构建工具

工具 版本 用途
Vite 7.2.x 构建工具
vue-tsc 3.1.x 类型检查
PostCSS 8.5.x CSS 处理
Autoprefixer 10.4.x CSS 前缀

Vite 配置

// vite.config.ts
export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  },
  build: {
    outDir: 'dist',
    sourcemap: false,
  }
})

3.5 功能库

版本 用途
@vueuse/core 14.1.x Vue 组合式工具
simple-keyboard 3.8.x 虚拟键盘
opus-decoder 0.7.x Opus 音频解码
uplot 1.6.x 实时图表
vue-sonner 2.0.x Toast 通知

3.6 国际化

版本 用途
vue-i18n 9.14.x 国际化

多语言支持

// i18n/en-US.ts
export default {
  common: {
    start: 'Start',
    stop: 'Stop',
    settings: 'Settings',
  },
  video: {
    noSignal: 'No Signal',
    streaming: 'Streaming',
  },
}

// i18n/zh-CN.ts
export default {
  common: {
    start: '启动',
    stop: '停止',
    settings: '设置',
  },
  video: {
    noSignal: '无信号',
    streaming: '正在推流',
  },
}

4. 外部依赖库

4.1 hwcodec (来自 RustDesk)

硬件视频编码库,支持多种硬件加速:

后端 平台 编码格式
VAAPI Intel/AMD Linux H264, H265, VP8, VP9
RKMPP Rockchip H264, H265
V4L2 M2M 通用 Linux H264
Software 通用 H264 (x264)

4.2 libyuv (来自 Google)

高性能 YUV/RGB 转换库:

// 支持的转换
MJPEG  YUV420
YUYV  YUV420
NV12  YUV420
RGB24  YUV420

// SIMD 加速
- SSE2/SSE4.1/AVX2 (x86)
- NEON (ARM)

4.3 ventoy-img-rs

Ventoy 启动盘支持库:

  • 创建可启动 USB 镜像
  • 支持多 ISO 文件
  • exFAT 文件系统

5. 协议和规范

5.1 RustDesk 协议

使用 Protobuf 定义的消息格式:

// protos/message.proto
message VideoFrame {
    bytes data = 1;
    int32 width = 2;
    int32 height = 3;
    VideoCodec codec = 4;
}

message MouseEvent {
    int32 x = 1;
    int32 y = 2;
    MouseButton button = 3;
}

5.2 WebRTC 规范

遵循标准 WebRTC 协议:

  • ICE (RFC 8445) - 连接建立
  • DTLS (RFC 6347) - 安全传输
  • SRTP (RFC 3711) - 媒体加密
  • RTP (RFC 3550) - 媒体传输

5.3 HID 报告描述符

USB HID 报告格式:

// 键盘报告 (8 字节)
struct KeyboardReport {
    modifiers: u8,      // Ctrl, Shift, Alt, GUI
    reserved: u8,
    keys: [u8; 6],      // 最多 6 个按键
}

// 鼠标报告 (相对模式, 4 字节)
struct MouseRelativeReport {
    buttons: u8,
    x: i8,
    y: i8,
    wheel: i8,
}

// 鼠标报告 (绝对模式, 6 字节)
struct MouseAbsoluteReport {
    buttons: u8,
    x: u16,             // 0-32767
    y: u16,             // 0-32767
    wheel: i8,
}

5.4 V4L2 接口

Video4Linux2 采集接口:

// 设备能力查询
VIDIOC_QUERYCAP

// 格式设置
VIDIOC_S_FMT
VIDIOC_G_FMT

// 缓冲区管理
VIDIOC_REQBUFS
VIDIOC_QUERYBUF
VIDIOC_QBUF
VIDIOC_DQBUF

// 流控制
VIDIOC_STREAMON
VIDIOC_STREAMOFF

6. 开发规范

6.1 Rust 代码规范

命名约定

// 结构体: PascalCase
pub struct VideoConfig { }

// 函数/方法: snake_case
fn start_streaming() { }

// 常量: SCREAMING_SNAKE_CASE
const MAX_FRAME_SIZE: usize = 1920 * 1080 * 4;

// 模块: snake_case
mod video_capture;

// trait: PascalCase
trait Encoder { }

错误处理

// 使用 Result 返回可能失败的操作
fn open_device() -> Result<Device, DeviceError>;

// 使用 ? 传播错误
let device = open_device()?;

// 自定义错误类型使用 thiserror
#[derive(Debug, thiserror::Error)]
pub enum DeviceError {
    #[error("Device not found: {0}")]
    NotFound(String),
}

异步代码

// 使用 async/await
async fn fetch_frame(&self) -> Result<VideoFrame> {
    let frame = self.capture.read_frame().await?;
    Ok(frame)
}

// 使用 tokio::spawn 启动后台任务
tokio::spawn(async move {
    loop {
        // 后台工作
    }
});

6.2 TypeScript 代码规范

类型定义

// 使用 interface 定义数据结构
interface VideoConfig {
  device?: string
  width: number
  height: number
  fps: number
}

// 使用 type 定义联合类型
type StreamState = 'idle' | 'starting' | 'streaming' | 'stopping'

组合式 API

// 使用 <script setup> 语法
<script setup lang="ts">
import { ref, computed, watch } from 'vue'

const count = ref(0)
const doubled = computed(() => count.value * 2)

watch(count, (newVal) => {
  console.log(`Count changed to ${newVal}`)
})
</script>

6.3 Git 提交规范

<type>(<scope>): <subject>

<body>

<footer>

类型 (type)

  • feat: 新功能
  • fix: Bug 修复
  • docs: 文档更新
  • style: 代码格式 (不影响功能)
  • refactor: 重构
  • perf: 性能优化
  • test: 测试
  • chore: 构建/工具

示例

feat(video): add H265 hardware encoding support

- Add VAAPI H265 encoder
- Update encoder registry
- Add fallback to H264

Closes #123

6.4 代码组织

模块结构

// mod.rs 作为模块入口
pub mod controller;
pub mod types;
mod internal;

// 重导出公共 API
pub use controller::Controller;
pub use types::{Config, State};

文件大小建议

  • 单个文件 < 1000 行
  • 单个函数 < 100 行
  • 嵌套深度 < 4 层

7. 构建和部署

7.1 构建配置

Release Profile

[profile.release]
opt-level = 3        # 最高优化
lto = true           # 链接时优化
codegen-units = 1    # 单代码生成单元
strip = true         # 移除符号
panic = "abort"      # panic 时中止

静态链接 Profile

[profile.release-static]
inherits = "release"
opt-level = "z"      # 优化大小

7.2 目标平台

目标 用途 工具链
aarch64-unknown-linux-gnu ARM64 (主要) cross
armv7-unknown-linux-gnueabihf ARMv7 cross
x86_64-unknown-linux-gnu x86-64 native

7.3 Docker 构建

# 多阶段构建
FROM rust:1.75 AS builder
WORKDIR /app
COPY . .
RUN cargo build --release

FROM debian:bookworm-slim
COPY --from=builder /app/target/release/one-kvm /usr/local/bin/
CMD ["one-kvm"]

8. 测试规范

8.1 单元测试

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_config_default() {
        let config = VideoConfig::default();
        assert_eq!(config.width, 1920);
        assert_eq!(config.height, 1080);
    }

    #[tokio::test]
    async fn test_async_operation() {
        let result = async_function().await;
        assert!(result.is_ok());
    }
}

8.2 集成测试

// tests/integration_test.rs
use one_kvm::AppState;

#[tokio::test]
async fn test_full_flow() {
    let state = AppState::new_test().await;
    // 测试完整流程
}

9. 性能优化

9.1 视频流优化

  • 零拷贝帧传递: 使用 Arc<Bytes> 共享帧数据
  • 帧去重: xxHash64 快速比较
  • 硬件编码优先: VAAPI > RKMPP > V4L2 M2M > Software

9.2 内存优化

  • 静态链接: 减少运行时依赖
  • 嵌入资源压缩: gzip 压缩静态文件
  • 缓冲区复用: 预分配帧缓冲区

9.3 网络优化

  • HTTP/2: 多路复用
  • gzip 压缩: 响应压缩
  • WebSocket: 双向实时通信
  • WebRTC: P2P 低延迟

10. 安全规范

10.1 密码存储

  • 使用 Argon2id 哈希
  • 随机盐值
  • 不存储明文

10.2 会话管理

  • HTTPOnly Cookie
  • 随机会话 ID
  • 会话超时

10.3 输入验证

  • 类型安全 (serde)
  • 路径验证
  • SQL 参数化查询

10.4 TLS 配置

  • TLS 1.3 优先
  • 自动证书生成
  • 证书轮换支持

11. 版本兼容性

11.1 最低系统要求

组件 最低版本
Linux Kernel 4.19+
glibc 2.28+
V4L2 5.4+ (推荐)
USB Gadget ConfigFS 支持

11.2 浏览器支持

浏览器 最低版本
Chrome 90+
Firefox 88+
Safari 14+
Edge 90+

12. 参考资源

官方文档

协议规范

相关项目