jQuery Mobile的离线/在线数据库身份验证/同步

时间:2013-08-27 15:46:11

标签: jquery html5 jquery-mobile offline-caching session-storage

情况:我有一个数据库和一个互动的网络应用程序,用于显示和更新科学数据表。我的任务是构建一个允许用户

的移动应用程序
  1. 为跟踪目的进行身份验证和识别自己离线 (使用存储在缓存中的预定义但动态的用户帐户和权限)
  2. 下载现场工作识别数据(可上网)
  3. 在现场制作和存储观察结果(无法访问互联网)
  4. 稍后将观察结果同步到在线数据库
  5. 问题:有关认证/下载/存储/上传必要数据以管理此类应用程序的最佳方式是什么,而不依赖于一致的互联网访问?如果两个人调整相同的读数,并且在同步之间发生一次更新,我如何跟踪哪些表和值已被更改,并防止更改丢失?

    当前思路:我目前的碰撞控制暂定策略是维护一个“同步”表,该表存储代表存储在sessionStorage中的每个在线数据库事务的JSON对象,并让应用程序不断验证其同步在上载数据之前,检查此对象是否存在对特定主键更新的潜在冲突。我希望能够在编辑阶段锁定元组,但由于互联网访问不一致,这似乎是不可能的。

    很抱歉,如果这是一个新问题,我是整个移动应用程序开发的新手......

    tl; dr 如何防止数据库的异步更改从进行和离线的移动应用程序覆盖/与另一个人对同一数据库的更改发生冲突?如何通过网络连接验证用户身份?

3 个答案:

答案 0 :(得分:2)

您是否听说过ajax通话方面的“竞争条件”[1]?有一个解决方案[2],你如何使你的服务器的ajax调用顺序而不是并发,因此它们按顺序运行。这适用于异步连接,因此不需要任何其他同步。

这里的诀窍是为此目的使用jQuery ajaxQueue [3]

我的消息来源:

[1] http://en.wikipedia.org/wiki/Race_condition

[2] How to make all AJAX calls sequential?

[3] http://plugins.jquery.com/ajaxqueue/

答案 1 :(得分:2)

关于同步,您可以查看jIO - 我们正在开发的一个开源库,它可以跨不同类型的存储同步JSON文档,并且具有超级简单的API。

有许多连接器可供使用(webDav,S3,xwiki等),您也可以编写自己的连接器,以便在您提供JSON数据时将JIO连接起来。

然后在客户端上,您可以使用客户端localhost和远程存储作为存储来设置复制修订存储:

 var jio_instance = jIO.newJio({
   "type": "replicaterevision",
   "storage_list": [{
     "type": "revision",
     "sub_storage": {<storage spec for your localhost storage>}
    }, {
     "type": "revision",
     "sub_storage": {<storage spec for your remote storage>}
    }]
 });

storage_list中的所有存储都将自动进行版本控制和同步。因此,如果用户处于脱机状态,检索文档,编辑并保存它(仅限于本地存储,因为用户处于脱机状态),jIO将在下次用户在线时尝试访问文件时发生冲突,因为当前版本在remote-storagelocalstorage不同。

然后,只需编写一个例程来解决因多个用户在线/离线编辑文档而导致的任何冲突=保留/合并/等等的版本。

访问文档非常简单。 JSON文档具有元数据和附件,您可以使用以下命令修改JSON文档:

  POST  > generate a new document
  PUT > update existing document
  GET > retrieve a document
  REMOVE > delete a document
  ALLDOCS > retrieve all documents
  PUTATTACHEMENT > add an attachment to a document
  GETATTACHEMENT > retrieve an attachment from a document
  REMOVEATTACHEMENT > delete an attachement from a document

可以这样调用:

  jio_instance.get({"_id":"your_doc_id"}, function (err, response) {
    // do something
  });

JIO还有一个complex-queries模块,允许在您的存储上运行类似数据库的查询。所以你可以这样做:

options = {
 query: '(author:"% Doe") AND (format:"pdf")',
 limit: [0, 100],
 sort_on: [['last_modified', 'descending'], ['creation_date', 'descending']],
 select_list: ['title'],
 wildcard_character: '%'
};

// run query
jio_instance.allDocs(options, function (error, response) {
  // do sth
});

如果您有任何问题,请与我们联系。

答案 2 :(得分:2)

对于未连接到网络的用户身份验证,我建议遵循以下路径:

在#2点,您正在通过互联网访问下载识别数据。显然,您必须在本地存储中以加密格式保存用户名和密码对。在访问远程区域中的应用程序时,即在离线模式下,这只能帮助您在同一设备上验证同一用户。最终手持设备是每个用户,您的应用程序将只保留该用户的历史记录;在这种情况下我认为绝对没问题。

避免碰撞;我建议增加设备与主服务器同步的次数。如果用户在网络中并对数据进行了一些修改,则后台同步操作应将这些更改同步到主服务器,其他用户应在预定义的时间间隔后同步。您同步数据的时间越长;冲突的可能性较小。但问题仍然是用户处于离线模式时对数据进行了修改。为此,我们无能为力。您的冲突管理代码应具有一些智能,例如哪些数据副本应具有更多优先权,即来自具有安全角色的X用户的数据或来自具有B安全角色的Y用户的数据或类似的数据。