开发一个在线文档我们可能要解决的对前端说问题: OT:一种解决协同问题的算法; OP:operation的简称,在OT中指的对前端说是一次操作; etherpad: 一个实现文档协同功能的开源库; easysync: etherpad中实现文档协同的核心算法,是个线OT算法的一种,主要用来处理文本协同; ot-json:ot算法的文档一种,顾名思义,需啥是技术主要用来处理结构化数据; Changeset: 一种描述文档更改的数据格式,用来表示整个文档的对前端说一次修改; ClientVars : 表示一篇文档的初始化数据,香港云服务器一般由连续的个线changeset组合而成; | :移动光标; ·:叠加; 什么是OT算法呢?我们先从头说起,如果要实现一个多人共同编辑文档的文档功能,我们最简单暴力的需啥做法是啥? 顾名思义,假如A在编辑文档,技术服务端直接将这个文档加锁,B如果在这个时候也加入了编辑,由于锁的存在,B的编辑直接被丢弃。可以看出,这种编辑锁的实现方式非常粗暴,体验极其糟糕,当然了,在很多公司(比如我们的某死对头公司)的一些wiki系统就是用这种实现方式,由于这种实现方式比较简单,而且体验很糟糕(内容丢失 Linux中有两个命令:diff和patch;如果我们能在JS中实现这套算法,那么多人协同编辑可以这样做: 我们来测试下: # 本地文档 $ echo 复仇者联盟 钢铁侠 美国队长 > test-local.txt # 生成用户A编辑后的文档 $ echo 复仇者联盟 钢铁侠 绿巨人 > test-userA.txt # diff两个文档 $ diff test-local.txt test-userA.txt > diff-test.patch # 查看diff-test.patch内容 $ cat diff-test.patch 3c3 < 美国队长 --- 从diff-test.patch内容可以看出,已经找出了两个文档不同的地方,然后我们再模拟下用户B的行为: # 生成用户B编辑的文档 $ echo 复仇者联盟 黑寡妇 美国队长 > test-userB.txt # patch方法更新文档 $ patch test-userB.txt < diff-test.patch # 查看test-userB.txt内容 $ cat test-userB.txt 复仇者联盟 黑寡妇 可以看到,用户B文档的第三行已经更新为了用户A修改后的“绿巨人”。但这种实现方式有个问题,因为他是基于行来进行对比的,就会导致很容易出现冲突,比如: # 生成文件1 $ echo 复仇者联盟 > local.txt # 生成文件2 $ echo 复仇者联盟钢铁侠 > userA.txt # diff对比 查看diff.patch内容: 1c1 < 复仇者联盟 --- 这就意味着如果两个人同时修改同一行,那必然就会产生冲突,我们测试下: # 生成文件3 $ echo 复仇者联盟美国队长 > userB.txt # patch 以上我们发现,假如原始文档是“复仇者联盟”,用户A修改为“复仇者联盟钢铁侠”,将diff结果传给服务端,服务端传给用户B,而用户B只是将文档改为了“复仇者联盟美国队长”,直觉上我们可以看出,这两处是不冲突的高防服务器,完全可以合并成“复仇者联盟钢铁侠美国队长”,但实际上的patch结果却是这样的: $ cat userB.txt.rej前言
名词解释
符号解释
正文
OT算法