概述
通过构建一套基于 WebSocket 的中继架构,实现前端浏览器与设备端 VNC 服务的无缝对接。方案的核心价值在于利用 MQTT 进行跨网段的信令控制,结合 Redis 进行连接状态的异步流转管理,最终通过 WebSocket 中继服务透传 RFB(Remote Framebuffer)原始字节流,使前端能够借助 noVNC 直接渲染设备桌面,实现低延迟、高可用的远程桌面访问体验。更方便地管理设备,监控设备。
整体架构
系统主要由以下六个核心角色协同工作,构成完整的信令与数据链路:
- 前端 (Frontend):用户交互入口,负责发起连接请求、状态轮询以及通过 noVNC 渲染远程桌面。
- 后端 (Backend):业务逻辑中心,负责会话管理、信令下发及状态流转控制。
- WebSocket 中转服务 (WS Relay):数据通道枢纽,负责将前端与设备端的 WebSocket 连接进行绑定,并双向透传 RFB 原始字节流。
- MQTT Broker:信令总线,负责将后端的连接指令可靠地推送到设备端。
- Redis:状态缓存中心,用于记录会话创建状态(如
WAITING、AGENT_READY)及超时控制,解耦前后端状态同步。 - 设备端 Agent:部署在目标设备上的守护进程,负责监听 MQTT 指令、连接本地 VNC 端口(5900)并作为 WebSocket Client 接入中继服务。

第一阶段:连接建立与信令下发
此阶段主要完成会话的初始化与设备端 Agent 的唤醒,采用 HTTP + MQTT + Redis 的异步协作模式。
- 前端发起请求:前端向后端发送 HTTP 请求,申请建立远程桌面连接。
后端初始化会话:
- 生成全局唯一的
session_id。 - 启动 WebSocket 中转服务实例,准备接收后续数据连接。
- 在 Redis 中创建缓存标记,将当前状态设为
WAITING,并设置合理的超时时间,防止僵尸会话。 - 通过 MQTT 向目标设备发送包含
session_id和连接 Token 的指令。 - 向前端返回
200 OK及session_id。
- 生成全局唯一的
- 前端启动轮询:前端获取
session_id后,立即启动定时轮询机制(GET /status?session_id=xxx),持续查询通道准备状态。 - Agent 响应指令:设备端 Agent 监听到 MQTT 指令后,首先连接本地 VNC 服务(默认端口 5900),随后作为 WebSocket Client 主动连接后端中继服务(
ws://relay:8080?sid=xxx)。
第二阶段:数据通道绑定与桌面渲染
当 Agent 成功接入中继服务后,系统进入数据链路打通阶段,前端正式接管远程桌面渲染。
- 状态更新:WebSocket 中转服务收到 Agent 的连接后,立即更新 Redis 中对应
session_id的状态为AGENT_READY。 - 前端获取连接地址:前端轮询接口检测到
AGENT_READY状态,后端返回该会话专属的 WebSocket 连接地址(ws_url)。 - 建立数据连接:前端使用 noVNC 库,基于获取的
ws_url发起新的 WebSocket 连接。noVNC 在此处充当协议转换器的角色,将 WebSocket 传输的 RFB 协议数据解析为浏览器可识别的 Canvas 绘图指令。 - 通道绑定与转发:后端中继服务识别到前端的连接请求,将其与已建立的 Agent WebSocket 连接进行绑定。绑定成功后,中继服务开始双向透传 RFB 原始字节流,远程桌面画面正式在前端呈现。
断开处理与资源清理
为保证系统资源的合理分配与安全性,方案设计了严格的断连清理机制:
- 双向联动关闭:无论是前端浏览器关闭/刷新,还是设备端 Agent 异常断开,WebSocket 中转服务均会立即感知,并主动关闭另一端的 WebSocket 连接。
- Redis 状态清理:在连接关闭的同时,后端立即清理 Redis 中对应的会话缓存,释放状态存储空间,避免无效状态残留。


Comments | NOTHING