Hocuspocus 是一套为您的应用程序带来协作的工具。
它基于Y.js(由 Kevin Jahns 开发),能够实时同步和合并来自客户端的更改,效果非常棒。但您也可以使用它来构建离线优先的应用程序,然后再同步更改。我们将确保解决冲突并始终保持所有内容同步。
Y.js 是什么?
Y.js 可以实时无冲突地合并来自用户的更改。与其他实现相比,它的性能超强,而且“令人惊叹”(Joseph Gentle,前 Google Wave 工程师,来源)。
Yjs CRDT 算法
用于协作编辑的无冲突复制数据类型(CRDT,Conflict-free Replicated Data Types)是操作转换(OT,Operational Transformation)的另一种方法。它们之间有一个非常简单的区别,OT 尝试通过转换索引位置以确保一致性(所有客户端最终使用相同的内容),而 CRDT 使用的数学模型通常不涉及索引的转换。比如链表。OT 是当前共享文本编辑的事实标准。OT 方法支持共享编辑,但没有一个真正的来源中心(中央服务器),需要保持数量众多的记录文档,虽然在实践中是可行的。CRDT 更适合于分布式系统,它为文档能够与远程客户机同步提供了额外的保证,同样也不需要一个真实的中心来源。 Yjs 实现 算法的一个修改版本。我们将会发表一篇论文来论述为什么这个方法在实践中如此有效。注意:由于操作组成了文档结构,所以我们现在更喜欢用
struct(结构)这个词。 适合于共享文本编辑的 CRDTs 的缺点是它们只会增加容量。虽然有一些 CRDTs 不会变大,但却没有利于共享文本编辑的特性(比如保存)。Yjs 对原始算法进行了诸多改进,减少了文档容量不断增加问题。我们不能在确保结构的唯一顺序的同时对已删除的结构(tombstone,墓碑)进行垃圾回收。但是我们可以这样做: 将之前的结构合并到一个结构中,可以减少元信息的数量。 如果内容被删除了,我们可以从结构中删除它。 如果我们不再关心结构体的顺序(例如父结构被删除),我们可以对墓碑进行垃圾回收。
状态向量
当同步两个客户端时,Yjs 能够只交换差异。我们使用 lamport 时间戳来标识结构,并跟踪客户端创建它们的顺序。每个结构都拥有一个struct.id = { client: number, clock: number}
,结构体的唯一标识。我们将每个客户端所期望的下一个clock定义为状态向量。这个数据结构类似于版本向量数据结构。但是我们只使用状态向量来描述本地文档的状态,因此我们可以计算远程客户端的缺失结构。我们不用它来追踪因果关系。
对于这种无冲突复制数据类型 (CRDT),应用更改的顺序并不重要。这有点像 Git,更改提交的时间并不重要。此外,每个数据副本的价值都相同。
这使您能够构建高性能的实时应用程序,为现有应用程序添加协作,同步感知状态并优先考虑离线。
使用 Y.js,您可以使用任何您喜欢的网络协议将更改发送到其他客户端,但最流行的是 WebSocket。
Hocuspocus Server 是一个 WebSocket 后端,它拥有快速启动所需的一切,可以将 Y.js 集成到您现有的基础架构中,并扩展到百万用户。提供程序是 Y.js 在不同用户之间建立通信或在浏览器中缓存更新的方式。Hocuspocus 自带提供程序,并且不再与其他 y 提供程序兼容(自 v2 起),因为我们支持多路复用以通过同一个 websocket 连接同步多个文档。 它带有 WebSocket 消息认证、用于向控制台添加详细输出的调试模式、一些事件挂钩、不同的重新连接策略、改进的错误处理以及用于 Awareness 协议的友好 API。所有 Y.js 提供程序都可以一起使用。其中包括 Hocuspocus 提供程序和原始y-websocket
数据的保存(webhook实现)
可看这里
这个是官方提供的一个扩展@hocuspocus/extension-webhook
,可以接入现有的api
当有连接的时候将获取到文档的id,然后根据id获取到文档,然后保存到数据库
当有文档的更新的时候,将更新后的文档保存到数据库
详细的数据接口看官方的文档。