如何将数据差异(可能是JSON)推送到服务器?

时间:2009-02-25 00:47:14

标签: javascript json diff

我将定期将一组基于文本的数据从网页推送到服务器,可能是JSON。

对于每次推送,没有,部分或全部数据可能已更改。为了减少我必须通过线路发送的数据量,我希望只在每次推送中发送变化的差异。

您知道任何预先制作的解决方案/工具/库:

  • 动态构建JSON的差异,因为对它进行了更改(以避免存储使用JavaScript编写的oldJson和newJson以及执行完全差异)(即用于客户端)
  • 在服务器端修补现有的一块JSON与JSON diff ,写在任何非Java或.NET的平台上^(需要在linux上运行,Java不是我所在的环境,也不是Mono)。

此外,这是解决这一特定问题的最佳方法吗? 是否有更好的方法来推送大量文本数据?

修改:一些澄清:

  • 可能的数据结构基本上是相当平坦的(在它是高度连接的意义上,所以任何链接都是基于ID的引用而不是实际的嵌套数据)节点集合。节点包含树的集合,这些树的叶子包含实际的“主要”数据,例如数字,字符串和ID。大多数数据更改将在叶子中。
    • 大多数叶子数据都非常小(原始数据或少于一段文本),但有些数据会很长(“丰富”文本页面)。
  • 目前我们可以严格一对一地考虑这个问题,即只有一个客户端连接(读/写)任何特定的数据结构。
  • 在复杂性方面保持服务器尽可能小是件好事 - 想法是尽可能远离服务器。虽然HTML5仍然大部分都不受支持,但我仍然需要一个来存储数据但是......

^ 您希望随机共享托管。我说的是你的好朋友PHP,Python,PERL,Ruby,那些全能。或者,可以很容易地安装在随机共享主机上。

8 个答案:

答案 0 :(得分:5)

这也是我一直在努力的事情。如果其他人提供比我更好的答案,我会非常感兴趣,但暂时还是......

首先,有http://www.xn--schler-dya.net/blog/2008/01/15/diffing_json_objects/

我个人无法让这个图书馆工作,但你的语言可能会有所不同。

另一种方法是不尝试使用DIFF算法解决问题。它的效率非常低,并且根据问题的不同,您可能会获得更好的性能指标,只需发送整个数据,即使您最终会重复自己。主要是非常小的数据块。显然,随着您需要传输的数据变得越来越大,将会出现转折点,但如果没有某种测量,转折点就不会很明显。这里的诀窍是,你的数据越大,你的差异计算也会越长。转折点仅取决于每种方法生长速度形成的两条线的交点,这两条线的线性或更差都取决于你的差异的实现方式。在最糟糕的情况下,您可能会看到中间有一个岛屿,其中diff会获得更好的性能,但是对于更大的数据集,它会再次向后传播,而只是通过网络发送它会更好。

在尝试diff之前的下一步是将数据访问包装在“get”,“set”和“delete”方法中,以跟踪正在进行的更改。您通过网络发送的数据基本上是这些方法使用的顺序日志,您可以在每次成功传输时从客户端刷新。在服务器端,您可以将此日志应用于服务器端数据,并使用与数据访问方法类似的服务器类型。这是一种比不需要太多处理能力的差异稍微更轻的解决方案。

最后,如果你要做diff,我能想到的最有效的方法是你是否可以将数据集分解为离散的“块”,每个块都有一个唯一的ID。然后当你运行差异时,差异的过程正好在“块”级别。也就是说,您所做的唯一比较是ID到ID。如果您更改了一个块,请为其添加一个新ID。你能负担得起diff算法的花费越少,运行所需的时间就越少。

或者,您可以简单地运行diff以检查特定对象是否已“更改”,并在检测到更改时立即停止,并简单地将该块标记为重新设置,而不是在更改时分配新ID。以其完整性发送,使用相同的ID更新服务器端的块。如果您的块有一些快速哈希算法可以用来快速建立相等性,那么这可以变得更加高效。

如果块的顺序无关紧要,或者您可以将序列存储为块本身的属性,而不是通过块的物理序列建模,那么您甚至可以通过ID键入块。然后发现差异只是列出对象A的键,然后在对象B上查找它们,然后是副Versa。这比“真正的”diff算法更容易实现,它具有O(a + b)性能(我认为)优于真实diff算法的最坏情况,如果你有可能获得我试图自己实现它,或者实现糟糕的实现。

答案 1 :(得分:4)

EtherPad通过将每个源更改转换为可交换,关联等数学运算来解决这样的问题。不过,我认为这是一个非常重要的问题,并且EtherPad能够组建业务解决这个问题。

编辑:有趣的是,这正是像Git这样的好DVCS解决的问题,而不是在浏览器上。

答案 2 :(得分:2)

我今天发布了一个小的jQuery插件,它在两个JS对象之间做差异。 http://plugins.jquery.com/project/jquery-diff

我将它用于一个应用程序,只向修改后的数据发送到服务器后端。

答案 3 :(得分:1)

为什么首先创建差异并不是更有效地挂钩更改数据的事件并根据更改生成更改的数据集?由于您的代码将嵌入浏览器中,因此您将仅限于JavaScript,因此生成差异可能会降低应用的性能。

答案 4 :(得分:1)

这不是JSON意识​​,但谷歌似乎使用了Docs的方法(他们上面提到的Etherpad问题的版本)。

http://code.google.com/p/google-diff-match-patch/

它不会识别JSON,但它允许您在JavaScript中生成有效的diff客户端,并让服务器使用适当的实现来应用它(Java,JavaScript,C ++,C#,Objective C,Lua)或者Python)。

对另一个问题的回答可能很有用,尤其是关于google-diff-match-patch的修改版本的部分:Textually diffing JSON

答案 5 :(得分:0)

某处有一个毕业论文,找到一个既能高效传输“什么是新的”又能与网络架构相得益彰的解决方案(缓存并在服务器上保存最少量的状态)。

我很好奇那里有什么;我一直在努力解决这个同样的问题,@布列塔尼的答案中的“大块”想法是我要去的地方,但不确定如何。

编辑:等待 - 我倒退了,我以为你在谈论服务器计算差异以发送给客户端。

也许您可以在模糊的细节中描述发送到服务器的客户端上的数据结构。如果可能的话,我不会根据JSON文本本身做到这一点;从Javascript中做差异。如果它是具有已知结构的项目列表,请跟踪您已发送到服务器的项目并发送其余项目。如果它是一个更复杂的数据集,不知道如何帮助你。

答案 6 :(得分:0)

此库计算完整的JSON差异(包括字符串差异):https://github.com/kbadk/json0-ot-diff

diff格式基于这个项目https://github.com/ottypes/json0,它提供了一个可以应用"的库。差异到对象。

此相关项目处理OT差异应用于持久数据,并向多个客户端广播差异以进行实时协作:https://github.com/share/sharedb

答案 7 :(得分:-2)

“我现在已经创建了一个返回两个JSON对象之间结构差异的方法。”

http://www.xn--schler-dya.net/blog/2008/01/15/diffing_json_objects/