Javascript JSON对象的增量编码

Javascript JSON对象的增量编码,javascript,json,node.js,Javascript,Json,Node.js,是否有一个标准库或工具用于计算JSON文档的差异并将其应用于JSON文档?基本上,我有一堆较大的文档,我希望在网络上保持同步,我希望避免每次我想要同步它们时都必须重新发送它们的整个状态(因为这些变量中的许多不会改变)。换句话说,我只想传输更改的字段,而不是重新传输整个对象。我认为采用以下方法会比较方便: //Start with two distinct objects on the server // prev represents a copy of the state of the obj

是否有一个标准库或工具用于计算JSON文档的差异并将其应用于JSON文档?基本上,我有一堆较大的文档,我希望在网络上保持同步,我希望避免每次我想要同步它们时都必须重新发送它们的整个状态(因为这些变量中的许多不会改变)。换句话说,我只想传输更改的字段,而不是重新传输整个对象。我认为采用以下方法会比较方便:

//Start with two distinct objects on the server
// prev represents a copy of the state of the object on the client
// next represents a copy of the state of the object on the server
//
//1. Compute a patch
patch = computePatch(prev, next);

//2. Send patch over the network

//3. Apply the patch on the client
applyPatch(prev, patch);

//Final invariant:
//   prev represents an equivalent object to JSON.parse(JSON.stringify(next))
我当然可以自己实现一个,但是有相当多的边缘案例需要考虑。以下是我能想到的一些简单(尽管有些不令人满意)的方法,例如:

  • 滚动我自己的JSON补丁程序。渐进地说,这可能是最好的方法,因为它可以支持JSON文档的所有相关特性,同时支持一些专门的方法,比如区分int、double和string(使用相对编码/编辑距离)。然而,JSON有很多特殊情况,我对在没有大量测试的情况下尝试这样做有点怀疑,因此我更希望找到一些已经解决了这个问题的方法,这样我就可以信任它,而不必担心由于JSON修补错误而出现的网络海森堡

  • 只需使用动态编程直接计算JSON字符串之间的编辑距离。不幸的是,如果客户机和服务器具有不同的JSON实现(即,它们的字段顺序可以不同地序列化),那么这就不起作用,而且二次时间操作的成本也相当高

  • 使用协议缓冲区。协议缓冲区有一个内置的diff方法,这正是我想要的,而且它们是一种很好的二进制序列化网络友好格式。不幸的是,由于它们也是严格类型化的,因此它们缺少使用JSON的许多优点,例如动态添加和删除字段的能力。现在这是我目前倾向的方法,但它可能会使未来的维护变得非常可怕,因为我需要不断更新我的每个对象

  • 做一些非常讨厌的事情,比如为每种类型的对象制定一个自定义协议,并希望我在这两个方面都能做到正确(没错!)

  • 当然,我真正希望的是stackoverflow上的某个人能够通过引用一个节省空间的javascript对象different/patcher来拯救这一天,该对象已经在生产环境和多个浏览器中得到了很好的测试

    *更新*

    我开始编写自己的修补程序,github提供了早期版本:


    我想,既然这里似乎没有太多内容,我会接受JSON修补程序的有趣测试用例列表作为替代答案。

    我在搜索JSON修补程序的实现时遇到了这个问题。如果你是滚动你自己的,你可能想在此草案的基础上


    我一直在github上制作json差异和补丁库(是的,无耻的插件):

    它使用Neil Fraser的diff_match_补丁库自动处理长字符串。 它可以在浏览器和服务器上工作(在两个环境上运行单元测试)。 (完整功能列表在项目页面上)

    您可能只需要为特定对象注入自定义diff/patch函数的选项,但这听起来并不难添加,欢迎您使用fork,甚至可以发送pull请求


    关于,JSON补丁标准已经更新

    您可以在

    中找到应用修补程序和生成修补程序的实现

    JSON补丁是一种用于描述对 JSON文档。它可用于避免在以下情况下发送整个文档: 只有一部分改变了。与HTTP修补程序结合使用时 方法,它允许在标准中对HTTP API进行部分更新 顺从的方式

    补丁文档本身就是JSON文档

    JSON补丁在IETF的RFC 6902中指定

    大多数平台和编程语言都有库

    在编写本文时,支持Javascript、Python、PHP、Ruby、Perl、C、Java、C#、Go、Haskell和Erlang()

    下面是javascript的列表

    • Diff和补丁,每周在NPM上下载509361次
    • Diff和补丁,每周在npm上下载5075次
    • 仅适用于npm中的补丁,2014每周下载
    • 仅应用补丁,npm每周下载1470次
    • Diff和补丁,每周在npm上下载400次

    到目前为止,每个人(包括我自己)都在使用FastJSON补丁库。它可以在NodeJS和浏览器中使用。

    既然您提到了“需要考虑的边缘案例很多”,那么如果您列举了需要处理的边缘案例,可能会对您的答案和子孙后代有所帮助,旁白:你的问题的后半部分很好地表明你已经考虑过这个问题,作为“变通办法”答案的一部分可能很好,但与问题无关,对吗?总是会添加一个
    标志。有一个
    标志?我不明白,“大”的定义很重要,它们如何改变也很重要。除非你有一个巨大的文档,它总是有大量的微小变化,否则这可能是过早的优化。已经有一些JSON修补程序库,比如步骤1(计算修补程序)的正确格式。如果您需要在第2步(通过网络发送补丁)中最小化JSON补丁大小,请使用library.@Damir,因为在升级您自己的libra时,还有许多其他紧凑且广泛使用的格式(FlatBuffers、protobuf、avro、bson、msgpack…)