后疫情时代,在线办公,多人协作已经成为现代企业的重要工作形式,现今许多产品都已经实现多人实时编辑同一文档的功能,比如说国内的石墨文档、腾讯文档;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

后端实现