WebSocket仅提供低延迟双向通道,协同编辑核心在于OT或CRDT算法保障一致性;须发送结构化原子操作而非整份文档,按文档ID路由、校验权限、处理断线重连。

WebSocket 实现协同编辑文档,核心是建立客户端与服务端的双向实时通道,让所有打开同一文档的用户能即时看到彼此的编辑操作。关键不在于“连上 WebSocket”,而在于如何设计操作同步协议、处理冲突、保证一致性。
用操作变换(OT)或 CRDT 同步编辑内容
直接发送整段文本或光标位置会引发冲突和带宽浪费。工业级协同编辑普遍采用操作同步模型:
- OT(Operational Transformation):每个编辑动作(如插入、删除)被封装为可序列化、可变换的操作对象。服务端收到操作后,先将其与其他并发操作做“变换”再应用,确保所有客户端最终状态一致。例如用户 A 在位置 5 插入“x”,用户 B 同时在位置 3 删除 2 个字符,服务端需调整 A 操作的位置为 3,再执行,避免错位。
- CRDT(Conflict-free Replicated Data Type):用支持合并的底层数据结构(如 RGA、Yjs 的 YText)替代原始字符串。每个编辑生成带逻辑时钟和唯一 ID 的增量更新,客户端可本地执行并自动合并,无需中心协调。适合离线场景,前端集成更简单(如使用 yjs + y-websocket)。
WebSocket 连接与文档路由管理
不能让所有用户共用一个全局 WebSocket 连接,必须按文档维度隔离通信:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 客户端连接时带上文档 ID(如
wss://editor.example.com/?docId=abc123),服务端根据 docId 将用户加入对应房间(room)。 - 服务端(如 Node.js + ws 库)维护 Map<docId, Set<WebSocket>>,广播操作仅推送给该文档的在线客户端。
- 需处理连接断开重连:客户端保存最后接收的版本号或操作 ID,重连后请求“从某操作之后的增量”来同步,避免全量拉取。
前端编辑器适配与事件捕获
原生 textarea 不够用,需接入支持协同的编辑器或自行封装:
立即学习“Java免费学习笔记(深入)”;
- 推荐使用已集成 OT/CRDT 的编辑器,如 Quill(配合 sharedb)、ProseMirror(搭配 y-prosemirror 或自研 OT 插件)。
- 若用自定义 contenteditable,需监听
input、selectionchange等事件,精确捕获用户操作类型、位置、内容,并转换为标准操作对象(如{type: 'insert', pos: 12, text: 'hello'})。 - 本地操作先应用到视图,同时发给服务端;服务端返回确认后,才标记该操作“已提交”。若收到冲突操作,需回滚本地未确认变更并重新计算。
基础但不可少:心跳、鉴权与错误降级
真实环境中,健壮性比功能更重要:
- 客户端每 30 秒发 ping,服务端响应 pong;超时未响应则主动重连,避免“假在线”导致操作丢失。
- WebSocket 握手阶段验证 JWT 或 session,拒绝非法 docId 访问;服务端对每个操作校验用户权限(如只读用户禁止发送编辑操作)。
- WebSocket 断开时,前端冻结编辑区域,显示“正在重连…”,并缓存用户新操作到内存(或 localStorage)。恢复连接后批量重发,失败则提示保存草稿。

















