离线/在线数据同步设计(Javascript)

58

我目前正在撰写一款离线Web应用程序,使用了所有html5的离线支持功能。 然而,我现在开始考虑编写同步模块,以确保任何离线数据都会发送到服务器并将服务器数据发送回客户端。 现在我确定这已经做过了,我的意思是这是影响移动设备和其他许多事情的经典设计问题。 所以我想知道有没有人能指导我找到这种类型的好的设计资源?

现在我真的不需要太复杂的设计,我的意思是我不处理多个用户访问相同数据,而且我很乐意不合并冲突(只取最新的),但我仍然希望有一个设计,将来可以允许我采用这些选项。

此外,是否有任何实现此类功能的开源项目? 如果许可证允许,我不介意借鉴别人的代码,并且我很乐意移植。

9个回答

13

我遇到了一个类似的问题。我决定采用纯 JSON 输入输出的方法。我在表单提交时采取的解决方案是:

  1. 捕捉表单提交事件
  2. 检查用户是否在线
  3. 如果 用户在线,则将表单作为普通表单 POST 提交
  4. 如果 用户离线,则将请求字符串化为 JSON 并在本地存储(我决定使用 Web SQL 数据库)。队列表仅包含 Uri 和 Payload。

然后我有一个全局事件钩子,可以监听在线/离线事件。当用户重新联网时,它会检查队列,如果队列中有项目,则将它们作为 JSON POST 请求发送。

如果你主要想要获取 JSON 数据并将其缓存以供离线使用,请看一下jquery.offline

在双向同步方面的挑战是,您需要使用任何已排队的 CRUD 操作更新本地缓存列表。

我希望找到更通用的方法来解决这个问题。


我已经实施了这种方法,但在其中遇到了问题。如果您有一个网站,那么用户可以在多个选项卡中打开该网站,用户可以选择在多少个选项卡中打开网站。我正在使用唯一标识符,我正在使用javascript为每个记录生成一个唯一的键,并在将记录放入数据库之前检查该键,但它不起作用,因为每个选项卡都具有相同的数据并且订阅了在线和离线事件,所以所有请求都是并行发送的,这意味着每个选项卡每次都会发送相同的请求。 - Muhammad Usama Mashkoor

10

我计划使用类似PouchDB的工具将数据本地存储,然后与远程Couch实例同步。


1
嘿!你成功了吗?我想听听你的经验。 - Nek

7

看看Derby吧,这是一个Node MVC框架,具有某些非常不错的同步和冲突解决功能。http://derbyjs.com/


5
Derby使用RacerJS进行数据同步,所以您不必选择完整的Derby框架。根据RacerJS自己的说法,它仍处于alpha版本。 - Per Quested Aronsson
RacerJS似乎不再积极开发。最后一次发布是在2017年7月,而且那只是一个小版本发布。 - mvermand

4
In our team, we have already developed an app that works in both offline and online modes. We use the following libraries:
- rack-offline - jquery - backbonejs - backbonejs-localStorage - backbonejs-queues - jammit 使用rack-offline我们可以缓存所有资源文件和jst模板以便在页面上呈现内容。backbonejs和backbonejs-localStorage有助于在客户端上制作MVC应用程序。这很棒,你应该尝试一下。我们总是使用localstorage来保存数据。例如,当我们创建帖子模型对象并保存到localStorage时,我们会触发队列进行同步(同时我们还有一个定时器后台工作者自动运行同步进程)。对于每个模型,我们都有单独的同步类,应该由队列同步触发器运行。如果您的navigator.onLine => true,我们将发送请求到服务器以更新数据。如果您关闭浏览器,无论如何您都不会丢失数据,因为您在localStorage中有队列。下一次客户端在navigator.onLine => true的情况下第一次加载时将同步数据。

如何使用rack-offline,您可以在github上检查我的小项目:

pomodoro-app

祝好运!


2

我曾经遇到过同样的问题,最终采用XML文件进行存储,并使用Git跟踪更改并在连接可用时自动提交。同步使用常规的git commit / push / pull命令在shell脚本中完成,cronjob启动该脚本。如果您将JSON存储在文本文件中,也可以使用此方法。


1

1

我个人建议您在indexedDB API之上编写一个包装器,以检查您是在线还是离线。

  • 如果离线,请仅在indexedDB中存储并将所有文档的persisted标志设置为false
  • 如果在线,请获取persisted为false的所有文档,并将它们存储在后端的mongodb或类似数据库中,然后在indexedDB和服务器上存储新文档,并将persisted标志设置为true。

我已经写了一个小型的包装器

您需要增强隧道以自动设置persisted标志,并将这些文档的同步隧道到后端。


1

我目前正在开发类似的Web应用程序。我决定采取以下工作流程:

  1. 表单并没有真正地提交 - “提交”按钮实际上会将序列化的表单数据保存到localStorage(在某个队列中)。这可以避免提交捕获的麻烦,并且避免编写额外的错误处理代码来处理表单提交期间的断开连接。
  2. 数据保存后,触发传输脚本以检查在线/离线状态。
  3. 当在线时,它尝试将最新的数据从队列发送到服务器(使用AJAX请求),并在成功后将其从队列中删除(并在短暂超时后继续发送下一个队列中的数据)。
  4. 它安排在一段时间后重新检查(通过setTimeout())。

1

如果你打算使用可能比较重的Ext JS / Sencha框架,它有一个很好的数据API,可以支持离线(如localStorage)和代理方式将数据写入本地然后传输到服务器。我使用的是Sencha Touch(适用于移动设备)。

要调试Web存储,请查看Weinre。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接