多人协作的同步机制:端到端加密、CRDT、实时协同
协作是怎么"实时"的
当你和同事同时在编辑同一个对象时:
- 你打了一行字 → 同事的屏幕上立刻看到这行字出现
- 同事把一个标题从 H2 改成 H1 → 你这边也立刻变成 H1
- 你们同时在不同位置插入了新段落 → 两边都保留,系统自动合并
这种"实时协同"能力不是来自云服务器的中心化编辑,而是来自 AnySync 协议 + CRDT 算法。
CRDT:无冲突复制数据类型
传统协同编辑(Google Docs、Notion)走的是中心化服务器路线:
你 → 服务器 → 所有人。服务器是唯一权威,冲突时"后保存覆盖前保存"。
Anytype 用 CRDT(Conflict-free Replicated Data Types):
每个设备都是平等的副本,本地可以独立编辑,离线也能改。同步时自动合并,永远不会冲突。
CRDT 怎么做到不冲突
CRDT 的核心思想:
- 每个操作都有唯一 ID(由设备 + 时间戳生成)
- 操作是可交换的——无论以什么顺序应用同一个 CRDT 状态,最终结果都一样
- 每个客户端有独立的向量时钟(Vector Clock)追踪"我知道对方哪些更新了"
类比:CRDT 就像两个人各自写日记,写完后互相交换日记页,然后合并在一起——永远不会丢任何一行字。
CRDT 解决了什么
| 场景 | 传统协同 | Anytype CRDT |
|---|---|---|
| 同一位置同时修改 | 后保存覆盖前者 | 两边都保留,系统自动插入 |
| 离线时编辑 | 回到线上会冲突 | 离线编辑正常进行,上线自动合并 |
| 延迟高时 | 操作可能丢失 | 最终一致,不丢操作 |
加密协作的完整链路
以两个人在同一个 Group Channel 里协作为例:
设备 A(张三) 设备 B(李四)
│ │
├─ Vault 本地加密 ├─ Vault 本地加密
│ │
├─ 编辑对象(本地 CRDT 更新) ├─ 编辑对象(本地 CRDT 更新)
│ │
├─ AnySync 打包加密增量 ──────► AnySync 解密增量 ──► 本地合并
│ │
└──◄──────────────── AnySync 加密增量 ◄──── 本地 CRDT 更新
关键点:
- 数据在 A 的设备上先加密再发出
- 在网络传输中始终是密文
- 在 B 的设备上解密后才进行 CRDT 合并
- 任何中间节点(包括 Anytype 的中继服务器)都看不到明文
同步触发时机
| 情况 | 同步行为 |
|---|---|
| 双方在同一局域网 | 直接 P2P 同步(最快) |
| 双方在不同网络 | Anytype Network 中继加密同步 |
| 一方离线 | 离线方本地继续编辑,上线后自动同步 |
| 一方在弱网 | 操作先在本地记录,网络恢复后批量发送 |
实时性不是"毫秒级"
坦白说,Anytype 的实时协同不像 Google Docs 那样毫秒级——因为数据要:
- 本地加密
- 传到中继(或 P2P)
- 对方解密
- CRDT 合并
这个链路比纯云服务长一点。但体验足够好——"打字延迟 1-2 秒"在大多数场景下完全够用。
实时性 ≠ 即时可编辑:即使对方正在编辑,你依然可以在同一时刻继续编辑——CRDT 保证两边的修改都不会丢。
协作中的常见问题
我能看到谁在编辑同一个对象吗
可以。Anytype 会在对象右上角显示"在线编辑者"的头像/首字母。但不会显示光标位置——这是出于隐私考虑(不想暴露"某人正在读/改哪一段")。
同事删了我写的东西怎么办
CRDT 保证每个操作都有来源 ID。如果同事删除了一个块,你可以:
- 从 Bin(回收站)恢复
- 从历史版本里查看谁删了什么
怎么退出一个协作者的共享
Group Channel → Settings → Members → 选择成员 → Remove from Space
被移除的人本地 Vault 会自动移除这个 Channel 的加密副本。