当多个用户正在查看记录并且1个人更新记录时,如何通知其他记录更新?

时间:2015-12-18 01:07:26

标签: javascript php mysql

在我的项目管理应用程序中,我想解决多个用户查看相同任务记录的问题,其中一个或多个用户更新一些任务数据,而其他人正在查看它。

这是一个场景......

用户#1 视图任务#1 用户#2 视图任务#1

现在用户#2 更新任务#1说明

用户#1 现在正在查看任务记录,但他的视图显示了不同的过时描述,因为用户#2 刚刚更新它!更糟糕的是,他可能想要自己编辑描述,这将完全覆盖用户#2的描述更新。

这是问题的一个例子。只需添加更多用户,问题就会倍增!

理想情况下,我会使用套接字或像Pusher.com这样的服务,在任何用户进行更新后立即更新所有用户的数据。然而,这个项目将在数百台服务器上运行,并且就服务器要求而言功能有限,因此套接字甚至像Pusher这样的服务都是不可能的!

解决方案的另一个想法是基于Twitter的作用。如果您查看人员Twitter页面,并且他们在您加载页面时发布新帖子。它会显示一条通知消息DIV,告诉您有多个新帖子,并为您提供一个链接,点击重新加载包含最新帖子的帖子流。

enter image description here

我相信类似的方法可以适用于我的项目。如果用户在查看该任务记录时对任何任务数据进行更新。它将在任务模式窗口中显示通知消息,告知用户任务数据已更新,并且他们应该重新加载任务。

为了完成这项工作,我知道需要在某个时间间隔内发出一些AJAX请求。

然后,AJAX请求需要比较在任务记录上进行的上次更新的时间戳,并将其与查看任务记录的用户开始查看它或上次重新加载任务的时间进行比较。

我觉得我的逻辑虽然错过了一块拼图?这一切都是正确的还是我错过了什么?

有人可以解释我是如何做到的,或者告诉我,我的想法是否正确?

我知道,简而言之,我只需要确定任务上次修改时间戳是否在其他用户开始查看任务之后。虽然我觉得用户的时间也应该更新?

更新

我完全忘记Stack Overflow在问题和答案上完成了这个确切的任务!当您在SO上查看页面并更新答案时,它将显示一条通知消息,告知您重新加载答案并提供重新加载答案的链接。这就是我想要做的!

StackOverflow使用Web套接字执行此操作,但在我的应用程序中,这是一个在许多不同的服务器配置上使用的插件,我不能使用套接字。我试图用AJAX实现类似的结果。即使是每30秒做一次AJAX请求来修改任务时间并将其与另一个进行比较以确定用户是否应该重新加载任务数据将在我的情况下起作用

enter image description here

2 个答案:

答案 0 :(得分:1)

你的问题过于宽泛,但你基本上是在描述一个Pub / Sub。

每当用户进入您的网站时,他都会获得一个令牌来识别他们。

如果他访问任务,他会订阅该任务,这意味着对他的任何修改都会被警告。

他轮询服务器以检查是否有任何警告。

实施

关于实施,您可以为每个用户的订阅设置一个列表。 使用您的示例:

User1订阅(Task1,Task2)

User2订阅(Task1)

对于每个订阅,您保留一些值,表示用户对该主题的最后状态(例如,上次修改时间戳)。

用户每隔n秒轮询一次您的应用程序。每当请求到达您的应用程序时,您都会检查用户的订阅,并检查时间戳是否已更改(如果它们具有最新的)。如果是,则更新用户拥有的最后一个状态,并检索更改的任务的新值。

需要考虑的事项

将不断访问此订阅列表,因此您可以将其存储在哪里。如果在内存中,请考虑您需要跨不同实例共享它(如果您负载平衡)。你可以使用Redis或类似的东西。

每次需要检索数据时都不需要访问数据库。如果有人订阅它,请将其保存在缓存中。

答案 1 :(得分:1)

这个概念和想法相当简单,实施不应该更加困难。如您所说,您需要为每项任务提供上次更新时间戳,以及客户端上的上次更新时间戳。通常,当用户正在查看任务时,您需要(在客户端,Javascript):

  1. 向服务器查询正在使用AJAX查看的任务上次更新时间戳。
  2. 如果正在查看的任务上次更新时间戳比客户端转到步骤5中的上次更新时间戳更大(更新)
  3. 等待(异步)n秒。
  4. 转到第1步。
  5. 通知用户,正在查看正在查看的任务
  6. 结束(因为客户已经知道任务已更新,因此无需继续轮询是否已更新)。
  7. 一种方法可能只是使用setInterval()创建一个异步间隔,一旦确定发生了更新就会被清除,然后会向用户显示一条消息。

    var lastUpdate = Date.now();
    var intervalDuration = 30000; // 30 seconds
    var interval = setInterval(function () {
        var xhr = new XMLHttpRequest();
        ...
        xhr.onload = function () {
            if (...) { // if the Task's Last Updated timestamp is newer than lastUpdate
                clearInterval(interval);
                // show message to user that the Task has been updated
            }
        };
    }, intervalDuration);
    

    我可以想象,在一个非常庞大的系统中,这种方法可能很容易,但对于非企业级解决方案或后续UI改进,这可以是一个快速,廉价,壮观的解决方案。

    当然,可能有更强大,更灵活的替代方案:long-polling or websockets