我一直在努力的应用程序的基本思想是允许用户组在闪存卡的“堆栈”上进行协作。最终,该应用程序将充当客户端 - 服务器系统(iOS应用程序作为客户端,Rails应用程序作为服务器)
正如我所见,这种设计的要求是这样的:
最初我只是去了简单的路线,并让客户端在每次同步时向服务器发送“批量”报告,这意味着每个堆栈的整个本地副本将被上传,然后服务器将处理所有这一切,在将整个新数据集发送给客户端之前,将其合并到之前客户端编辑的主副本中,然后将保存此准确副本以供离线查看和编辑。
我看到的这个问题,牢记我的设计要求,主要是它非常低效。客户端应用程序不仅要浪费时间上传和下载所有这些数据,还必须将所有新信息写入其本地数据存储,即使其大部分与前一个副本相同。我也无法理解服务器如何以高效,合理的方式理解冲突的编辑。
所以这就是我想出的:
每当客户端对共享堆栈进行更改时,除了更改自己的数据库副本之外,它还会记录日志中的更改,包括更改内容,方式,时间和人员。客户端下次与服务器同步时,无论是在几天还是几天内,都会将此操作“收据”发送到服务器,而不是整个本地数据副本。
在那里,服务器首先为后代存储这些操作,然后再对数据的服务器副本执行所有更改。然后,它使用此收据数据库来获取自客户端上次与数据库同步以来对堆栈的所有相关更改。然后只将这些发送回客户端,客户端在其自己的本地副本上运行更改。
使用客户所做的所有更改的日志,服务器可以决定哪些更改使其他更改无效(例如,如果用户删除了卡,然后在同步此更改之前,另一个用户编辑了理智卡,则删除将失效)。虽然实施起来很复杂,但理论上这对我的合并问题来说是一个理想的解决方案。
那你觉得怎么样?
这是一个可行的解决方案吗?你看到我的总体规划中有任何明显漏洞吗?
谢谢!
答案 0 :(得分:1)
要注意的一件事是不信任设备中的时间作为算法的一部分:
Can I Rely on the iOS Device Clock Being Correct?
我在该主题上的回答谈到了这个问题以及合并/交错操作。
您可能需要考虑两个用户是否在同一张卡上编辑相同的冲突数据。由于您无法信任时间,因此客户端确实知道上次同步时的最后一个“服务器时间标记”,因此您可以记入上次同步服务器标记的所有更改。这样做可以奖励更频繁同步的客户端,因为它可以通过唯一可以确定的事项(服务器的时间)来交换更改。
希望有所帮助。绝对是一个复杂的主题,正确(和一般)。