实时协作-yjs基本理解

April 11, 2017

Yjs 是一个开源的 JavaScript 库,它实现了一种称为 CRDT(Conflict-free Replicated Data Type)的数据类型,这是一种可以在多个副本之间无冲突地复制和合并的数据类型。Yjs 允许多个用户在没有中心协调者的情况下并发地编辑共享的数据。

目前对 Yjs 的基本原理理解如下:

  1. 数据结构:Yjs 实现了多种 CRDT 数据结构,如 Y.Text(用于协作文本编辑)、Y.Array(用于协作列表编辑)等。这些数据结构都有一个共同的特点,即它们可以在没有中心协调者的情况下并发地被多个用户修改,而最终能够达到一致的状态。
  2. 唯一标识符:Yjs 为每一个操作(比如插入一个字符、删除一个列表元素等)分配一个全局唯一的标识符。这个标识符是由用户的唯一 ID 和一个递增的计数器组合而成的。Yjs 使用这个唯一标识符来追踪每个操作,这样就可以处理并发的操作,并确保所有副本的最终一致性。
  3. 向量时钟:Yjs 使用一种称为向量时钟的技术来跟踪操作的顺序。向量时钟是一个映射,它将每个用户的唯一 ID 映射到该用户的操作计数器。通过比较两个向量时钟,Yjs 可以确定两个操作的顺序关系。
  4. 操作日志:每当一个操作被应用到 Yjs 的数据结构时,这个操作都会被添加到操作日志中。Yjs 可以使用这个操作日志来生成一个差异(delta),然后将这个差异发送给其他的副本。接收到差异的副本可以使用这个差异来更新自己的状态。
  5. 冲突解决:当两个并发的操作修改了同一个数据元素时,Yjs 需要进行冲突解决。Yjs 的冲突解决规则是基于唯一标识符的:如果两个并发操作有相同的唯一标识符,那么它们实际上是同一个操作;如果它们的唯一标识符不同,那么 Yjs 会根据唯一标识符的顺序来决定哪个操作应该被接受。

Yjs 的设计使得它可以在任何网络协议(如 WebSocket、WebRTC、HTTP 等)上工作,可以与任何数据持久化库(如 IndexedDB、LevelDB 等)配合使用,也可以和任何协作编辑框架(如 CodeMirror、ProseMirror 等)集成。


目录