Существует ли стандартная библиотека или инструмент для вычисления и применения различий в документах 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, а также поддерживать некоторые специализированные методы для создания таких вещей, как разные ints, doubleles и strings (с использованием относительного расстояния кодирования/редактирования), Однако у JSON много особых случаев, и я немного стараюсь сделать это без большого тестирования, и поэтому я бы предпочел найти то, что уже решает эту проблему для меня, чтобы я мог доверять ей, и не нужно беспокоиться о том, что сеть Heisenbugs появляется из-за ошибок в моем патче JSON
-
Просто вычислите расстояние редактирования непосредственно между строками JSON, используя динамическое программирование. К сожалению, это не сработает, если у клиента и сервера есть разные реализации JSON (т.е. Порядок их полей может быть сериализован по-разному), а также довольно дорого - это квадратичная операция времени.
-
Использовать буферы протокола. У буферов протокола есть встроенный метод diff, который делает именно то, что я хочу, и они являются красивым бинарным сериализуемым сетевым форматом. К сожалению, поскольку они также строго типизированы, им не хватает многих преимуществ использования JSON, таких как возможность динамического добавления и удаления полей. Сейчас это подход, к которому я сейчас склоняюсь, но это может сделать будущее обслуживание действительно ужасным, поскольку мне нужно будет постоянно обновлять каждый из моих объектов.
-
Сделайте что-нибудь действительно противное, например, создайте собственный протокол для каждого типа объектов и надейтесь, что я получу его в обоих местах (да, правильно!).
Конечно, я на самом деле надеюсь, что кто-то здесь, в stackoverflow, должен пройти и сохранить день со ссылкой на объект javascript с разным пространством, отличающийся /patcher, который был хорошо протестирован в производственных средах и в разных браузерах.
* Update *
Я начал писать свой собственный патчер, ранняя версия его доступна в github здесь:
https://github.com/mikolalysenko/patcher.js
Думаю, поскольку здесь, похоже, не так много, я вместо этого буду принимать в качестве альтернативного ответа список интересных тестовых примеров для патчера JSON.