Данные:
1. Время синхронизации брать с сервера.
2. На клиенте хранить собственно данные, последнее время синхронизиции (прислонное с сервера) и id данных, измененных после последней синхронизации. Если данные еще нет, то последнее время синхронизации принимаем за 0.
3. На сервере хранить данные с дополнительным полем last_update или журнал изменения (отдельная таблица) с временем изменения и id записи (В любом случае такой журнал можно сжать до размера самих данных, удалив старые дубликаты id).
Описание:
1. Клиент стучится на сервер отправляю последнее время синхронизации и изменненые данные после последней синхронизации.
2. Сервер сохраняет данные если не было конфликтов, и возвращает обновленные данные после последнего пользовательского обноновления (можно без пользовательских обновлений), новую дату обновления. А клиент обновляет данные и удаляет отосланные id записей после синхронизации.
3. Если были конфликты (дата последнего изменнения пользователя меньше последнего изменения на сервере и хеши данных отличаются), то можно отложить обновление и передать пользователю данные для мержа, при этом обновив last_update таких записей до даты синхронизации возвращаемой пользователю. После чего пользователь снова синхронизируется. Если опять возник конфликт, то повторять до тех пор, пока не разрешится.
Запрос:
{time: , data: []}
Ответ:
{time: , data: [], mergeData: []}
Замечания:
Те localStorage хранит до 5 метров по спецификации, то возможно не стоит заморачиваться по поводу большого объема данных. Хотя можно добавить на сервер метод, который будет возвращать количество обновлений в байтах по последнему времени изменений и завязать дополнительную логику. Если данных больше 5 мб, то стоит использовать
indexed db или
web sql (привет ie 8 и 9), но в браузерах реализован асинхронный API.