使用PhoneGap与服务器同步数据的策略

31
我正在使用AngularJS开始我的第一个PhoneGap项目,这是一个使用REST API作为后端的数据库驱动应用程序。首先,我不会在本地存储任何数据,因此没有互联网就无法做太多事情。
然而,我最终希望它可以在本地存储数据,并在有互联网连接时进行同步,因为我知道我个人有时会禁用手机上的互联网连接(如乘飞机、低电量)或没有信号。我想知道是否可以向我推荐一些关于这种同步的好资源,例如一些推荐的库?或者一些讨论它们的缺陷以及如何规避它们的文章。我已经谷歌了一下,但我现在不知道该问什么问题。
另外,我的意图是先建立一个依赖于互联网的应用程序,然后再添加同步功能...这是一个好主意吗?还是说我自己给自己挖了一个坑?我需要从一开始就构建同步功能吗?
我有个人建议先构建一个本地应用程序,而不是先做互联网部分,从某种逻辑上来说这是有道理的。远程存储对我来说很重要。我知道该决策与我的应用程序目标有很大关系,但从构建的角度来看,最终目标是本地存储+互联网存储和双向同步,哪个更容易?还是说没有区别? 首先,我想使用UUID而不是顺序整数主键。我也考虑过为每个设备分配ID,并在其生成的任何密钥前加上前缀,但这似乎很微妙。有人使用过这两种技术吗?你有什么想法吗? 我想我需要一个好的系统来告诉我哪些数据已经同步。在客户端,我想任何创建/编辑的记录都可以标记为要同步。但在服务器端,您有多个客户端,这样就行不通了。我想您可以拥有一个last_updated时间戳,并同步自上次成功同步以来更新的所有内容。
如果记录在多个地方进行了编辑怎么办?如果两个客户端都进行了编辑并希望同步,那么合并时就会出现一些不确定性,就像在git或其他版本控制系统中合并分支时一样。你如何处理这个问题?我猜git是通过存储每个提交的差异来实现的。我想你可以存储差异?我越想越觉得这听起来越复杂。我是过度思考还是欠缺思考?
客户端存储怎么办?我考虑过SQLite或PhoneGap本地存储(http://docs.phonegap.com/en/1.2.0/phonegap_storage_storage.md.html)。有什么建议吗?同步将通过REST API进行,交换JSON数据,所以我认为实际上将数据存储为JSON或类似JSON的东西易于转换会很好。另一方面,如果我要交换某种数据差异格式,也许这就是我需要存储的内容?

有人用过这个吗?http://pouchdb.com/ 看起来与我很多关注的问题相关,但如果你已经走过这条路,我很想听听你的想法。 - eimajenthat
1个回答

26

基于我的经验,我将根据与同步部分相关的经验回答您的问题,因为我没有足够的PhoneGap经验,所以将跳过关于PhoneGap本地存储与SQLite的问题。

我想知道是否可以向我推荐一些好的资源来实现此类同步。有什么推荐的库?

有许多开源项目可用于将PhoneGap应用与远程服务器同步。但是,您可能需要根据自己的需求进行调整或实现自己的同步功能。以下列出了一些开源项目。如果您搜索网络,就肯定已经知道它们了。

此外,您可能还考虑其他选项,但这取决于您的服务器端:

此外,我的意图是先使其依赖于互联网,然后再添加同步...这是一个好主意吗?还是我自己给自己挖了坑?我需要从一开始就构建它进行同步吗?

我认为同步功能更像是附加模块,不应与您的业务逻辑紧密耦合。一旦您开始考虑同步测试策略,您将意识到如果将同步设施与主代码解耦,测试会更容易。

我认为您可以尽快使用最少所需功能启动您的应用程序而不进行同步。但最好提前考虑架构和添加同步功能的方式。

首先,我考虑使用UUID而不是顺序整数主键。我还考虑过为每个设备分配一个ID,该ID在其生成的任何键上带有前缀,但这似乎很精细。有人使用过这两种技术吗?有什么想法吗?

这取决于您的项目规格,特别是您的服务器端。例如,Azure移动服务仅允许使用整数类型作为主键。虽然唯一标识符作为主键在分布式系统中非常方便(也有一些缺点)。

关于分配设备ID-尽管我不知道您的项目细节,但我不确定其意义。请查看我们系统中使用的同步算法(在多个Android客户端和中央SQL Server之间使用REST进行双向同步)。

那么在多个位置编辑的记录呢?如果两个客户端编辑,然后想要同步,您对合并有些模糊,就像在git或其他版本控制系统中合并分支一样。您会如何处理?我猜git通过存储每个提交的差异来解决这个问题。我猜您可以存储差异?我越考虑它,它听起来越复杂。我是过度思考还是低估了它?

这就是您需要考虑如何处理系统中的冲突解决的地方。

如果系统中冲突的可能性很高,例如用户经常更改相同的记录。那么最好跟踪记录在同步中已修改的字段(列),然后一旦检测到冲突:

  1. 迭代冲突中服务器端记录的每个修改字段
    • 将服务器记录的每个修改字段与客户端的相关字段进行比较。
    • 如果客户端字段没有被修改,则没有冲突,只需用服务器字段覆盖它。
    • 否则就存在冲突,需要将两个字段的内容保存到临时位置以供报告使用。
    • 在同步结束时生成有冲突记录的报告。

设备ID的想法是让每个设备使用自己的顺序ID,但前缀为其自身唯一的设备ID。例如,我的设备将获得ID 1,而您的设备将获得ID 2。然后,我创建一个ID为1的记录,但它将类似于2-1或2-00001(如果您喜欢)。当我创建我的第一条记录时,它将是1-1或1-00001。因此,每个设备保留自己的序列,并按顺序创建ID,但它们可以合并,因为前缀使它们有所区别。我不喜欢那个解决方案,尽管我无法确定原因。 - eimajenthat
很多有用的信息 @Havrl。谢谢! - eimajenthat
我倾向于使用UUID。我的服务器端将由我指定。最初我考虑使用PostgreSQL或MySQL,但是当我了解了CouchDB后,它听起来很有吸引力。 - eimajenthat
移动应用程序的主要用例是记录购买。您不会经常编辑现有数据,但这是可能的。当您进行编辑时,您不会编辑每个人的数据,只会编辑自己的数据。但是,一个帐户将是每个家庭的,因此您将有2-4个用户共享给定的记录集,并且他们可能会相互干扰。想法。如果我使用NoSQL解决方案,例如CouchDB或MongoDB,我是否可以为每个帐户提供自己的集合。与同步无关,但对于搜索更快。 - eimajenthat
CouchDB更适合于数据同步。 - Denis C de Azevedo

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