时间轴

Created with Raphaël 2.2.02026年05月20日 周三尝试cadus地图协作,第一个版本开始2026年05月21日 周四加了构造线,多段线、点、多段线命令完成图形建立功能,缺编辑修改功能增加C++获取用户选择集2026年05月24日 周日删除基本成功2026年05月31日 周日缺椭圆、样条曲线缺控制点方式判断,夹点拖曳,命令行回显历史完成样条曲线和椭圆,缺颜色、图层、线型特性,标注还得跟随字体样式标注样式2026年06月03日 周三夹点拖曳同步,反过来不行,esc键可以取消夹点2026年06月04日 周四完成夹点拖曳同步2026年06月05日 周五补充copy、mirror,阵列命令引用块功能有待验证2026年06月06日 周六阵列能否先记住选择的源实体guid阵列同步,还未删除源实例,阵列编辑还不行2026年06月18日 周四属性添加了图层、颜色、线型、线型比例、线宽-全局宽度和高程2026年06月19日 周五完成绘制命令的特性同步未完,待续……

工作流程

用户空闲 > idle_delay_ms → 远程命令到达 → ProcessCommandQueue 获取锁
                                            │
                                    设置 MODEMACRO = "远程协作同步中..."while 循环处理命令
                                            │
                                    每条命令执行前检查 m_userIsActive
                                            │
                              ┌─ 用户开始操作 → re-queue 剩余命令 → break
                              │
                              └─ 用户仍空闲 → 继续执行
                                            │
                                    恢复 MODEMACRO 原值


服务器(无状态,纯转发)
    │
    │  广播 "MOVE 实体 A"
    │
    ├──→ 用户B 的 AutoCAD 插件
    │       └── m_commandQueue: [MOVE A]
    │       └── 空闲 → 执行
    │
    ├──→ 用户C 的 AutoCAD 插件
    │       └── m_commandQueue: [MOVE A]
    │       └── 操作中 → re-queue → 等空闲
    │
    └──→ 用户D 的 AutoCAD 插件
            └── m_commandQueue: [MOVE A]
            └── 空闲 → 执行

发送方 → WebSocket 服务器 → 广播给所有接收方
                                │
                    ┌───────────┼───────────┐
                    ▼           ▼           ▼
                 用户B        用户C        用户D
              (空闲,执行)  (操作中,入队)  (空闲,执行)

ExecuteRemoteCommand(msg)
  │
  ├─ 1. acDocManager->lockDocument(doc)  ← 获取写锁
  │     │
  │     └─ 如果用户正在绘图 → 锁已被用户持有 → 失败,返回 false
  │
  ├─ 2. 创建/修改实体(写数据库)
  │
  └─ 3. acDocManager->unlockDocument(doc) ← 释放写锁

                    commandWillStart
    ┌──────────────────────────────────────┐
    │                                      │
    ▼                                      │
 USER_ACTIVE ──(1s无操作)──> PROCESSING ──(用户开始操作)──┐
    ▲                          │                          │
    │                          ▼                          │
    │                    队列处理完毕                      │
    │                          │                          │
    └──────────────────────────┘──────────────────────────┘
接收方 状态 行为
用户 B(空闲) lockDocument 成功 立即执行 ✅
用户 C(操作中) lockDocument 失败 re-queue,等空闲后重试 ⏳
用户 D(空闲) lockDocument 成功 立即执行 ✅

锁冲突的本质

场景 锁持有者 远程命令
用户空闲 无人持锁 lockDocument 成功,正常执行
用户正在画线 用户命令持锁 lockDocument 失败,返回 false → re-queue
远程命令执行中 远程命令持锁 用户点击 → 用户等待锁释放

所以我们不能”不锁定”,只能”选择合适的时机去锁定”。 这就是你之前说的”用户优先”原则——用户操作时我们不抢锁,等用户空闲 1s 后再尝试获取锁执行远程命令。

作者:秦晓川  创建时间:2026-06-19 15:00
最后编辑:秦晓川  更新时间:2026-07-05 22:55
上一篇:
下一篇: