实时协同建模需通过websocket广播结构化原子指令(如createnode、movenode),服务端按room隔离转发,客户端本地预渲染+服务端权威校验,并支持带时间戳的历史消息补全。

用 WebSocket 实现实时协同建模工具,核心不是“连上就行”,而是让多个用户操作同一模型时,图形状态、参数变更、拓扑关系都能在毫秒内同步且不冲突。关键在于把建模动作抽象成可广播、可排序、可收敛的结构化指令,并让客户端与服务端各司其职。
建模操作需转为轻量语义消息
不能传整个模型文件或 canvas 截图。应将用户行为映射为原子操作指令,例如:
-
创建节点:
{"type":"createNode","id":"n-456","typeClass":"Router","x":200,"y":150} -
拖动节点:
{"type":"moveNode","id":"n-456","dx":12,"dy":-8,"timestamp":1717023456792} -
连线/断连:
{"type":"connect","from":"n-456","to":"n-789","port":"out-0"} -
修改属性:
{"type":"updateProp","id":"n-456","key":"bandwidth","value":"1Gbps"}
每条消息必须含 唯一 ID + 时间戳(或 sequenceId)+ 操作主体 ID,用于后续排序、去重与冲突判定。
WebSocket 8.18.2 是该协议规范的一个重要迭代版本,主要优化了连接稳定性与数据传输效率。它通过全双工通信机制,允许客户端与服务器在单一长连接上实时交换数据,大幅降低传统 HTTP 轮询的开销。该版本增强了心跳保活、自动重连及二进制帧传输能力,适用于即时通讯、在线游戏及金融行情推送等低延迟场景,为开发者提供更可靠的实时网络交互基础。
服务端按房间隔离 + 广播不处理逻辑
每个建模会话对应一个唯一 room ID(如 model-proj-2026-abc),用户连接时通过 URL 参数携带该 ID:
- 服务端用 Map
> 管理房间,只向同房间成员广播 - 不做操作变换(OT)或合并计算——WebSocket 只做“原样转发”,避免引入延迟和单点状态维护负担
- 对控制类消息(如清空画布、切换视图模式)同样走同一通道,确保所有端 UI 状态一致
客户端本地预渲染 + 权威校验
提升响应感的关键策略:
- 用户拖动节点时,立即更新本地坐标并重绘,不等服务端返回
- 同时将 moveNode 消息发往服务端;收到广播后,比对
id和timestamp - 若本端消息 timestamp 更晚,说明网络延迟导致服务端后发先到,直接丢弃该广播
- 若 timestamp 相同但坐标不同(如多人同时拖同一节点),以服务端版本为准覆盖本地(即“服务端为权威源”)
断线恢复与历史补全
新用户加入或重连时,不能只收新消息:
- 服务端内存缓存最近 30 秒的操作日志(LRU 队列,500 条以内),格式与实时消息完全一致
- 连接建立后立即推送带
"isHistorical": true标识的消息流,客户端跳过撤销栈记录、禁用动画、批量绘制 - 重连时附带上次收到的 maxTimestamp,服务端只补发该时刻之后的操作,避免重复或遗漏










