VDI 云桌面项目:终端登录、桌面列表、RDP/Moonlight 会话、看门狗及云管端模块
Go to file
2026-11-05 19:15:31 +08:00
console 构建:保留 console 目录结构 2026-10-28 21:05:58 -04:00
deploy 构建:保留 deploy 目录结构 2026-10-28 21:05:59 -04:00
docs 运维:固定虚拟PCI设备并补充过夜观察与电源策略 2026-11-05 19:15:31 +08:00
platform 构建:保留 platform 目录结构 2026-10-28 21:06:01 -04:00
terminal 运维:固定虚拟PCI设备并补充过夜观察与电源策略 2026-11-05 19:15:31 +08:00
tools 运维:固定虚拟PCI设备并补充过夜观察与电源策略 2026-11-05 19:15:31 +08:00
.gitattributes 功能:完善2K串流、显示恢复与输入优化 2026-11-03 13:43:50 +08:00
.gitignore 功能:统一 Moonlight 会话并优化云桌面启动体验 2026-10-30 15:11:21 +08:00
MEMORY.md 文档:同步多系统桌面接入与调优进度 2026-11-04 19:12:54 +08:00
PROJECT_CONTEXT.md 功能:完善2K串流、显示恢复与输入优化 2026-11-03 13:43:50 +08:00
README.md 文档:同步多系统桌面接入与调优进度 2026-11-04 19:12:54 +08:00

VDI 云桌面项目

本项目是一套面向企业云桌面场景的“云—管—端”VDI 解决方案,目标是在 RK3528 云终端上提供统一的用户登录、云桌面选择、远程会话接入、设备管理和运维能力。

当前仓库采用 monorepo 结构,包含终端嵌入式软件、云端服务、Web 管理控制台、部署配置和配套工具。

当前开发阶段:终端 POC 与产品流程验证。仓库内已实现的功能、已验证的功能和规划功能会在本文档中分别标注。

一、项目目标

终端产品的目标使用流程:

盒子开机
  -> 设备身份自动登录
  -> 获取并展示可用云桌面列表
  -> 用户选择 Windows / Ubuntu / 麒麟等桌面
  -> 获取一次性连接票据
  -> 启动 Moonlight 会话
  -> 会话结束后返回桌面列表

总体系统关系:

RK3528 云终端
  -> 自研管理平台 API
  -> Proxmox VE / KVM 虚拟化平台
  -> Windows / Ubuntu / 麒麟云桌面

终端不会直接调用 Proxmox API。桌面生命周期、用户授权、连接信息和协议策略统一由管理平台下发。

二、仓库结构

vdi-cloud/
├─ terminal/                    # 终端嵌入式软件
│  ├─ meta-vdi/                 # Yocto 层:BSP、内核、设备树、U-Boot、配方
│  ├─ kiosk-shell/              # Qt 全屏壳:桌面列表、Moonlight 会话、看门狗
│  ├─ vdt-agent/                # Rust:注册、心跳、命令、日志
│  ├─ ota-updater/              # Rust:OTA 签名校验、A/B 切换、回滚
│  └─ usb-monitor/              # Rust:USB 监听、挂载与重定向策略
├─ platform/                    # Go 云端服务
├─ console/                     # Vue 3 + TypeScript Web 管理控制台
├─ deploy/                      # Docker Compose、Helm、离线部署包
├─ docs/                        # 方案文档、实施记录、测试证据和运维资料
└─ tools/                       # 烧录、构建、压测和 CI 工具

当前有实现代码的模块为 terminal/kiosk-shell,其余模块保留目录结构,后续按里程碑逐步开发。

三、当前功能

1. 终端登录与桌面列表

已实现:

  • 开机后使用设备 SN 作为当前身份,自动进入桌面列表;
  • Windows、Ubuntu、麒麟三类桌面卡片;
  • 桌面连接可配置:每张卡片有“设置”按钮,可配置服务器地址(支持 IP、域名或 VPN 隧道地址)、Sunshine 应用名、分辨率和帧率;
  • 连接配置持久化在 ~/.config/vdi-terminal/desktops.json, 地址为空的桌面显示“待分配”且不可连接;
  • 老环境自动迁移:首次运行会读取 client.conf 里的 server 地址填充 Windows 桌面;
  • Ctrl+Alt+Shift+M 管理菜单提供“桌面连接设置”统一入口;
  • 会话退出后返回桌面列表。

不同客户部署环境的桌面地址不同:换环境时在“设置”里改地址即可,不需要改代码。 VPN 属于网络层能力(盒子上的 VPN 客户端建立隧道后),地址字段直接填隧道地址即可。

设备身份自动登录是正式认证 API 上线前的临时实现。后续通过 DesktopService 适配层接入真实的用户认证、桌面列表和一次性连接票据接口,页面流程不需要重写。

2. Moonlight/Sunshine 会话

已实现:

  • MoonlightSession 使用 QProcess 参数数组启动 moonlight-qt;
  • 不通过 Shell 拼接用户输入,降低命令注入风险;
  • H.264 软件解码;
  • 绝对鼠标模式;
  • 点击连接后立即锁定操作,保证任何时刻最多一个 Moonlight 会话;
  • 解析 Moonlight 输出,只有测试解码成功、渲染器选定且全屏串流窗口已激活后才淡出过场;
  • ARM/X11 环境通过 GL_IS_SLOW=0 缩短不可用 DRM 路径的探测时间;
  • 连接阶段有结构化耗时日志和 30 秒就绪超时,失败时自动关闭错误窗口并返回列表;
  • 会话进程退出后自动返回桌面列表;
  • vsync、frame-pacing、性能叠图等低延迟参数可配置;
  • 独立 Moonlight 启动脚本保留作调试用途,但不再作为产品开机入口。

2026-11-04 现场已接通 Windows、Ubuntu、麒麟三种桌面的正常选择与连接流程。Ubuntu 当前采用 1080p / 30 FPS 配置,麒麟已升级真实 2K / 30 FPS 配置与30Mbps;两者使用 libx264 软件编码,盒子使用 RKMPP 硬解。麒麟后续采用逐主机limited视频范围协商,同场景动态短测由约21提高至29FPS,仍未达到Windows水平,长期性能及物理输入延迟尚未验收。配置、备份与证据见 Linux 桌面接入记录、麒麟2K调优记录 和 鼠标掉帧继续排查。

3. 状态机

当前终端状态机:

BOOT
  -> CONFIG / LOGIN
  -> AUTHENTICATING
  -> DESKTOP_LIST
  -> CONNECTING
  -> SESSION
  -> RECONNECT
  -> DESKTOP_LIST / ERROR

4. Monitor 看门狗

已实现独立 vdi-kiosk-monitor 进程:

  • 监控 kiosk-shell 进程是否退出;
  • 通过心跳文件检测主进程假死;
  • 异常退出后自动重启;
  • 连续启动失败后熔断;
  • 子进程独立进程组,结束时清理整棵进程树,避免遗留孤儿串流进程。

四、技术栈

终端

  • C++17
  • Qt 5 Widgets / Qt Test
  • Moonlight Qt
  • 当前开发环境:Armbian + LightDM + Xorg
  • 正式目标环境:Weston + Wayland

云端(规划)

  • Go
  • PostgreSQL
  • VictoriaMetrics
  • HTTPS + MQTT
  • Proxmox VE / KVM / VFIO

Web 控制台(规划)

  • Vue 3
  • TypeScript
  • Vite
  • Element Plus

五、构建 kiosk-shell

1. 依赖

目标设备或 ARM64 构建环境需要:

sudo apt install \
  build-essential cmake ninja-build pkg-config \
  qtbase5-dev libqt5widgets5 libqt5test5

Moonlight 会话还需要安装:

sudo apt install moonlight-qt

2. 编译

cd terminal/kiosk-shell
cmake -G Ninja -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTING=ON
cmake --build build
QT_QPA_PLATFORM=offscreen ctest --test-dir build --output-on-failure

编译产物:

build/kiosk-shell
build/vdi-kiosk-monitor

3. 运行

在当前 X11 开发环境中:

export DISPLAY=:0
export XAUTHORITY="$HOME/.Xauthority"

./build/vdi-kiosk-monitor -- ./build/kiosk-shell

产品自启入口为:

vdi-kiosk-monitor -> kiosk-shell

Moonlight 只能在用户登录并选择桌面后由 kiosk-shell 启动,不应与 kiosk-shell 分别设置开机自启。

六、本地配置

终端基础配置路径:

~/.config/vdi-terminal/client.conf

Moonlight 调试配置路径:

~/.config/vdi-terminal/moonlight.conf

当前配置文件仅用于 POC。正式版本中,终端身份、配置版本和连接策略应由 vdt-agent 从管理平台同步。

不要将以下信息提交到仓库:

  • Windows 或平台账号密码;
  • Proxmox root 密码;
  • Gitea 密码或访问令牌;
  • 终端设备密钥;
  • Sunshine 管理账号密码;
  • 私钥、证书和一次性连接票据。

七、当前联调环境

项目 当前环境
终端硬件 RK3528 PRO DDR4
终端架构 ARM64
终端系统 Armbian / Ubuntu Noble
图形环境 LightDM + Xorg(POC)
云平台 Proxmox VE 9
Windows 云桌面 Windows 10 22H2
Moonlight 服务端 Sunshine
当前串流分辨率 1920×1080@60Hz

具体 IP、测试账号和密码不写入 README,统一通过本地配置或部署环境变量管理。

八、已知限制

  1. 终端用户认证、桌面列表和连接票据目前是本地演示实现,尚未接管理平台 API;
  2. Ubuntu 和麒麟桌面尚未配置实际连接地址;
  3. 当前 Moonlight 使用软件解码,RK3528 的 VPU/MPP 硬解尚未打通;
  4. Sunshine 当前使用软件编码,未启用 NVENC;
  5. 当前仍是 X11 POC,尚未完成 Weston/Wayland/DRM 零拷贝路径;
  6. USB 重定向、OTA、Agent、管理平台和 Web 控制台尚未开发完成。

九、下一步计划

按优先级:

  1. 保持终端、Sunshine 和虚拟显示器三端分辨率及色彩空间一致;
  2. 将 GTX 965M 直通 Windows VM,使 Sunshine 使用 NVENC;
  3. 定义并联调终端用户认证、桌面列表和一次性连接票据 API;
  4. 实现 Ubuntu、麒麟桌面连接配置;
  5. 适配 RK3528 MPP/VPU 硬解;
  6. 切换到 Weston/Wayland 正式显示路径;
  7. 开发 vdt-agent、OTA、USB、云端服务和 Web 控制台。

十、开发规范

  • 已验证、已实现、待验证和规划中必须明确区分;
  • 终端不能直接调用 Proxmox API;
  • Moonlight 是当前唯一远程会话协议,连接参数由管理平台连接票据决定;
  • 所有密钥和密码只能通过安全配置注入,不得提交到 Git;
  • 正式代码变更应通过编译、真机测试和会话恢复测试;
  • 本 README 随功能、接口、目录和验证结论持续更新。