6.7 KiB
6.7 KiB
UE nDisplay WebSocket 协议草案
目的
本协议定义后端到 UE nDisplay 集群运行时之间的场景同步契约。
设计目标:
- 由 UE 主节点单点接入后端
- 使用全量快照重建完整场景
- 使用增量更新降低同步成本
- 支持控制帧和显示配置
- 支持序列号、重放和重同步
适用范围
该协议建立在通用 WebSocket 协议之上,参考 websocket_protocol.md。
新增的核心内容是 ue_scene 频道。
连接模型
客户端
- UE 主节点连接
ws://<backend-host>:8000/ws?token=<access_token> - UE 渲染节点不直接连接后端场景通道
订阅
UE 主节点建议订阅:
ue_scenealertsdashboard
协议规则
- 每次场景更新都带单调递增的
sequence - 增量更新必须包含
base_sequence - UE 如果发现序列断裂,应先发
sync_request - 服务端优先返回可重放的增量历史;无法重放时返回全量快照
- 后端始终发送地理坐标,UE 本地负责转成球体世界坐标
- 控制消息与场景消息分离
消息类型
connection_established
服务端 -> 客户端
{
"type": "connection_established",
"timestamp": "2026-04-17T02:30:00.000Z",
"data": {
"connection_id": "conn_primary_node_01",
"server_version": "0.19.0",
"heartbeat_interval": 30,
"supported_channels": [
"ue_scene",
"alerts",
"dashboard",
"datasource_tasks"
]
}
}
subscribe
客户端 -> 服务端
{
"type": "subscribe",
"timestamp": "2026-04-17T02:30:01.000Z",
"data": {
"channels": ["ue_scene", "alerts"]
}
}
sync_request
客户端 -> 服务端
{
"type": "sync_request",
"timestamp": "2026-04-17T02:30:05.000Z",
"data": {
"channel": "ue_scene",
"reason": "initial_connect",
"last_sequence": null
}
}
reason 常见值:
initial_connectsequence_gapmanual_resyncprofile_changed
data_frame 全量快照
服务端 -> 客户端
{
"type": "data_frame",
"channel": "ue_scene",
"timestamp": "2026-04-17T02:30:06.000Z",
"data": {
"update_type": "full",
"sequence": 12,
"cluster_time": "2026-04-17T02:30:06.000Z",
"display_profile": {
"profile_id": "polarized-wall-a",
"stereo_mode": "polarized",
"screen_width_m": 3.0,
"screen_height_m": 2.0,
"target_refresh_hz": 120
},
"camera_state": {
"mode": "auto_cruise",
"path_id": "global_overview",
"fov": 42.0
},
"payload": {
"meta": {
"generated_at": "2026-04-17T02:30:06.000Z",
"total_records": 20800,
"state_hash": 123456789
},
"layers": {
"satellites": {
"revision": 111,
"items": []
},
"supercomputers": {
"revision": 222,
"items": []
},
"gpu_clusters": {
"revision": 333,
"items": []
},
"submarine_cables": {
"revision": 444,
"items": []
},
"landing_points": {
"revision": 555,
"items": []
},
"alerts": {
"revision": 0,
"items": []
}
}
}
}
}
data_frame 增量更新
服务端 -> 客户端
{
"type": "data_frame",
"channel": "ue_scene",
"timestamp": "2026-04-17T02:31:00.000Z",
"data": {
"update_type": "incremental",
"sequence": 13,
"base_sequence": 12,
"cluster_time": "2026-04-17T02:31:00.000Z",
"meta": {
"generated_at": "2026-04-17T02:31:00.000Z",
"total_records": 20805,
"state_hash": 123456790
},
"changes": {
"gpu_clusters": {
"added": [],
"updated": [],
"removed": []
},
"submarine_cables": {
"added": [],
"updated": [],
"removed": []
}
}
}
}
control_frame
客户端 -> 服务端
{
"type": "control_frame",
"timestamp": "2026-04-17T02:32:00.000Z",
"data": {
"target": "ue_scene",
"command": "set_camera_mode",
"arguments": {
"mode": "manual",
"camera_id": "operator_cam_1"
}
}
}
常见命令:
set_camera_modeset_camera_pathfocus_entityset_layer_visibilityset_alert_filterset_display_profilepause_auto_cruiseresume_auto_cruise
control_acknowledged
服务端 -> 客户端
{
"type": "control_acknowledged",
"timestamp": "2026-04-17T02:32:00.050Z",
"data": {
"target": "ue_scene",
"command": "set_camera_mode",
"accepted": true
}
}
heartbeat
双向
{
"type": "heartbeat",
"timestamp": "2026-04-17T02:32:30.000Z",
"data": {
"action": "ping"
}
}
服务端返回:
{
"type": "heartbeat",
"timestamp": "2026-04-17T02:32:30.020Z",
"data": {
"action": "pong"
}
}
场景实体结构
每个场景实体建议包含:
identity_typerevisiongeovisualmetricslabelsstatus
示例:
{
"id": "gpu_clusters:123",
"entity_type": "gpu_cluster",
"revision": 987654321,
"geo": {
"lat": 35.9327,
"lng": -84.3107,
"alt": 0.0
},
"visual": {
"style": "pulse_marker",
"size": 1.0,
"color": "#FF8C42"
},
"metrics": {
"name": "Frontier"
},
"labels": {
"title": "Frontier",
"subtitle": "Oak Ridge, US"
},
"status": {
"health": "normal",
"alert_level": "none"
}
}
同步策略
UE 主节点建议这样处理:
- 保存本地最后一次成功应用的
sequence - 收到增量帧时检查
base_sequence - 若
base_sequence不等于本地序列,则立即发sync_request - 如果服务端能重放缺失增量,则按顺序依次应用
- 如果服务端无法重放,则接收并应用新的全量快照
- 场景更新应在主节点原子提交,再交给集群同步显示
服务端重同步规则
服务端建议行为:
initial_connect:直接返回全量快照manual_resync:直接返回全量快照profile_changed:直接返回全量快照sequence_gap:优先尝试从历史缓存中回放增量- 如果历史缓存不完整:回退到全量快照
- 如果客户端已是最新序列:返回空变化增量或保持静默
集群职责约束
- 只有 UE 主节点接收后端场景同步消息
- 渲染节点不直接重放后端消息
- 服务端表达的是场景意图,而不是每个节点的底层渲染状态
推荐的后端扩展
- 为
ue_scene增加更多真实可视化层 - 将告警/BGP 事件并入统一场景层
- 为控制命令增加真正的状态持久化与回执
- 为主节点断线重连补状态恢复策略