我有一个网络应用程序,其中客户端编辑器正在编辑服务器端已知的非常非常大的文本。

客户可以对此文本进行任何类型的修改。

什么是最 网络效率高 如何以服务器理解的方式传输结果差异?另外,由于这将发生在客户端(Javascript),我也希望它“快”(或者至少不会明显慢)

一些场景:

  • 用户修改一个字符
  • 用户在随机位置修改多个句子
  • 用户删除所有内容并产生空白文本。

我不能使用类似 diff 的语法,因为它不是网络效率较高的语法,它会检查行,其中示例 1 和 3 将产生可怕的差异(尤其是最后一个,结果将比旧的本身更多)。

有人有这方面的经验吗?用户操作的数据非常大——大约 3-5MB 的文本,上传整个“新”内容是一个很大的禁忌。

需要明确的是,我正在寻找传输的“协议”,字符串比较不是问题。

有帮助吗?

解决方案

我对这个主题不是很熟悉,但我可以向您介绍一个可能非常有用的开源(Apache License 2.0)项目。

它是由 Google 工程师用多种语言(包括 JavaScript)编写的 Diff、Match 和 Patch 库,并用于多种在线协作编辑服务。

以下是资源列表:

其他提示

一种简单的方法,假设您知道服务器上的副本不会更改,只需发送编辑列表(删除和添加),其中删除表示为开始和结束索引,添加表示为作为起始索引和要插入的文本。

如果您有多个简单的差异算法可供使用(我不确定“字符串比较不是问题”到底是什么意思),您还可以检测移动或复制的文本块,并将它们作为开始发送移动或复制的文本片段的结束索引,以及插入文本的目的地。

请注意,您需要确保跟踪您的索引是引用原始文档还是迄今为止编辑的文档。避免此问题的一个简单方法是始终从文档末尾到开头进行编辑;那么早期的编辑不会影响后来的编辑指定的偏移量。

有关此类方法的示例,请参阅 ed 格式化那个 diff -e 输出。这基本上是可以输入到 ed 面向行的文本编辑器. 。如果您希望发送绝对最小的差异,您可能需要进行基于字符的索引而不是基于行的索引,但相同的基本方法也可以工作。

用户执行的任何编辑都可以有效地分解为:从 X 中删除长度 Y;在 X 处插入文本“whatever”。X 和 Y 是距文本开头的字符偏移量;Y是字符数;“whatever”是任意字符串。你说你不需要帮助计算差异,但一个例子是 这里, ,除了它的输出比您需要的更丰富,但确实识别“删除和插入”,因此,只需更改输出部分即可。

可以调整将数据发送到服务器的确切格式,但我认为这样做没有太多里程 - 等待测量,我首先发送命令为 D(删除)或 I(插入),十进制数字,以引号形式插入的字符串。一旦您对正在执行的实际传输有了一些统计数据,您就可以看到数字(十进制与二进制)和引号中有多少开销,但我怀疑这可能没有那么有意义(如果证明是这样,那么所有排序您可以尝试的一些事情,例如给出从最新插入或删除点的偏移量,而不是总是从头开始,以使事情更快)。

您可以每隔几秒钟对用户正在执行的操作进行采样,然后仅发送最后几秒钟内的增量更改(如果有)——这样,您发送的每个数据包都会很小,并且如果网络连接或用户的计算机/浏览器崩溃,用户不会丢失太多工作。

您可以每 500 毫秒发送一次更改,因此,过去 500 毫秒内所做的任何更改都会被发送,但只有在发生更改时才发送数据。

在这种情况下,您可以发送更改的单词的位置并只发送整个单词,但我希望该位置来自文本的前面。

它不会是几句话,但可能涉及几个单词,但是,如果您按更改顺序发送它们,那么结果应该是一致的。

因为有很多方法可以进行编辑——即使是在 500 毫秒这样的短时间内——包括 在文档内部或外部拖放或剪切和粘贴大段文本——我不知道是否会有某种东西能够很好地涵盖所有场景。从表面上看,这当然不能回答您的问题,但与更改界面以限制文本大小并将现有文本分解为更小的部分相比,我会仔细考虑开发和维护此类内容的麻烦。

也许这在你的情况下是不可能的,但如果是的话,我想最终以这种方式回避问题并在编辑后发送完整的文档会少很多麻烦。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top