多人协同编辑的那些事儿
后疫情时代,在线办公,多人协作已经成为现代企业的重要工作形式,现今许多产品都已经实现多人实时编辑同一文档的功能,比如说国内的石墨文档、腾讯文档;Google的Google Docs等。
要实现多人协同是一件不容易的事,本文并非基于相关原理,提出了一套全新的解决方案,而是基于现有框架的基础上实现了多人协同编辑。
多人协同的数据冲突
实现多人协同编辑的难点之一在于解决数据冲突,以下是数据冲突的实例说明:
首先,假设目前只有用户A和用户B,文档初始内容为12
。用户A将一个字符A插入到文档结尾,该操作在本地应用后,客户端A的文档内容都是12A
。此时客户端A发送请求insert(2, "A")
给服务端,其意思就是在位置2插入字符A,然后服务端会将这个操作转发给客户端B。
然后,用户B在收到insert(2, "A")
之前也在文档的结尾插入了字符B,该原子操作被本地应用后,客户端B的文档内容是12B
,之后客户端B通过网络发送请求insert(2, "B")
到服务端,其意思就是在位置2插入字符B,服务端再将该原子操作转发给客户端A。
紧接着,用户B收到了来自服务端转发的用户A的操作,在位置2插入字符A,即客户端B的文档内容从12B
改为12AB
。
最后,用户A收到了来自服务端转发的用户B的操作,在位置2插入字符B,即客户端A的文档内容从12A
改为12BA
。
结果是客户端A的文档内容是12BA
,客户端B的文档内容是12AB
,内容不一致,不符合预期。
多人协同的解决方案
目前实现多人协同编辑的方法有CRDT(Conflict-free Replicated Data Types)方法和OT(Operateional Transformation)算法。本文最后采用的是OT算法。
OT算法
OT算法是一种用于协作编辑系统中的冲突解决算法。在多人同时编辑同一文档的情况下,该算法可以自动解决由于编辑操作顺序不同而产生的文档内容冲突。
工作原理
- 每个参与编辑的客户端都保存着文档的本地副本
- 用户对文档进行编辑操作时,这些操作会被发送到其它用户
- OT算法会对其他客户端的操作进行转换操作,最终确保所有客户端文档数据的一致性
由此可见,OT算法的核心就是按照一定的规则执行操作转换,该规则如下:
- 保证原操作的语义,即转换后的操作产生的效果与原操作一致,但是不一定能保留用户的操作意图
- 确保最终文档内容的一致性,即所有用户的文档内容是一致的
实现案例
shareDB介绍
shareDB是一款基于OT算法实现JSON文档协同的开源框架。该库基于Node.js开发,同时实现了多人协同的前端和后端,开发者只需要安装shareDB的依赖即可使用。
以下就对shareDB中的一些概念进行介绍。这些内容只是笔者阅读官方文档后的个人理解,如有错误,还请指出。
类型插件
shareDB框架
环境搭建
如前文所说,shareDB基于Node.js,因此使用该库实现多人协同,相关后端只能使用Node.js框架,至于后端框架的搭建,可见本站的其它博客。同时使用如下指令将shareDB引入前/后端项目中。1
npm install --save sharedb