客户端如何检测页面是否应该更新



我在一个页面中有一个表,显示摘要数据
这些数据来自汇总数据库表。如果基础表得到更新,我需要刷新页面中显示的这个表
我知道的方法是每X秒重新加载一次页面
但我感兴趣的是在表实际更新时更新表
这方面的标准解决方案是什么?我唯一能想到的方法是在表中添加一些额外的列,以更新行ID,并以某种方式每隔X秒对该列进行"轮询"。我认为这是可行的,但这似乎是一个可怕的解决方案,我想知道解决这个(我认为是常见的)问题的标准方法是什么。

更新:
只是添加更多内容。我的问题不那么笼统。我只有一个特定的代码部分来更新表,更新完全在我的控制之下。它不像一个由多个来源更新的表格

通信系统

你有多种方法可以创建一个自动更新的动态页面(如Facebook)。

  1. 基本最基本的方法是,如您所说,每X秒轮询一次服务器(具有JavaScript无限$.ajax({});每X秒调用一次的循环)来查看服务器上是否有新的东西。这是一个有效的解决方案,过去也曾使用过。

  2. 推动第二种方法是长轮询或推送,也很常用。如果你在后端使用异步框架(即Node.js、Tornado、Twisted等),你可以很容易地使用这个解决方案,因为它几乎没有性能成本。对于其他后端框架,如PHP或Django,这不是一个好的方法,因为你为每个请求创建一个进程,该进程保持打开状态,直到更新了内容或到达Http连接超时(据我所见,人们大部分时间都在长轮询上设置了30秒的计时器)。

  3. 插座这是最新的、最不受支持的方法。并非所有浏览器都可以访问WebSockets。和以前一样,异步框架更适合这种方法。

如果你有一个基于CGI的框架(这意味着WCGI、FastCGI等),比如Django、PHP、Flask等,那么你最好采用第一种方法,这是最基本的方法。占用任何其他资源对您的服务器来说都是非常昂贵的。如果你有一个异步后端,那么第二种或第三种方法都可以。我必须说,web套接字方法有点难以进入、编程正确和支持框架。

数据库系统

在您选择了要用作通信系统的内容后,您的数据库设计需要反映您需要执行的新查询类型。
假设用户希望查看自加载页面以来的所有新更改。

  • 一个简单的方法是在每行上都有一个日期,这是最后一次更改的时间。查询自上次查询时间以来更改的所有行。

  • 一种更复杂的方法是实现一个完整的通知系统。对于每一个更改或新行,都会添加一个关于它的新通知。你可以在用户和通知之间建立关系,以了解他是否已经看到了它,并安排每24小时一次删除旧关系的作业。但很快,这一切都变得臃肿起来。我更喜欢使用NoSQL数据库(像CouchDB这样的JSON数据库)作为通知系统。您可以轻松更改文档的结构,并为所有通知创建特定的视图。使用它比使用关系数据库更为宽松。如果你想知道你的数据在用户加载页面后是否发生了变化,你所要做的就是查询通知的类型(你正在观察哪些数据/表的变化),并获取创建日期比上次查询时间新且未查看的数据/表。由于表总是反映最后一个状态,因此在页面加载时,您会查询表,然后只查询更改或此处称为通知。

我的个人看法

如果你有一个CGI后端,对于一个完整的通知系统,你需要在你的后端结构上添加一个特定的后端结构,用于长轮询或套接字。不要忘记,您的客户端还需要具备如何对新的服务器处理程序做出反应的逻辑。为了快速获得结果,如果你的工作指定了这一点,你更适合在页面中只使用一个脚本,每隔1分钟左右重新加载一次页面。

如果您已经在使用异步框架,您可以很容易地添加通知功能,但需要对数据库进行艰苦的工作,尤其是在通知处于关系型框架中的情况下。如果你决定专门为此添加一个新的数据库,它还需要在你的后端添加大量的应用程序逻辑,再加上它的培训

希望我能帮忙,加油!

解决这样的问题有很多不同的方法。最好和最有效的解决方案将涉及服务器的一些帮助,以了解何时/发生了什么变化。以下是一些想法:

  1. 使用到服务器的websocket连接,这样服务器就可以在后端数据发生更改时发出通知,然后客户端可以请求新的数据。

  2. 使用原始页面传递某种"最后一个事务id",然后在轮询间隔使用ajax调用询问服务器自上次事务id以来数据是否发生了更改。如果发生了更改,请请求新数据。如果没有,那就没什么可做的。这会让你在什么都没有改变的情况下,无法一遍又一遍地获取数据。

  3. websocket的替代方案是http推送的长轮询,也可以使用http推送(特别是在不支持websockets的客户端中),以允许服务器在有新数据时通知客户端。

轮询是最简单的方法。它看起来是这样的:

(function poll() {
$.ajax('/myTableData', {
success: function(data) {
updateTable(data);
},
complete: function() {
setTimeout(poll, 8000); //every eight seconds
}
});
})();

然后将端点/myTableData添加到服务器中。

支持实时协作的谷歌文档在撰写本文时进行了民意调查。然而,更复杂的是,民意调查是"长"的:它们持续的时间与新数据到达所需的时间一样长,或者经过一定的时间(例如40秒),以先到者为准。这减少了轮询的数量。

或者,您可以查看现代浏览器(IE 10+)支持的websocket。

这是WebSockets的前提(http://socket.io对于垫片)。您需要(如前所述)一个服务器(如Node.JS)来支持WebSocket功能——大多数现代web浏览器都在客户端支持这个API。

Web套接字API(http://www.w3.org/TR/2012/CR-websockets-20120920/)允许浏览器连续地将数据传送到服务器(反之亦然)。

如果数据库记录已更新,则可以设置一个触发器,将此数据传回客户端。以评论板系统为例(与我们在StackOverflow上使用的系统完全相同)——由于网络上已经有大量的信息可用,我认为没有必要在这里详细介绍。

进一步阅读和工具:

  • http://www.html5rocks.com/en/tutorials/websockets/basics/
  • https://developer.mozilla.org/en-US/docs/WebSockets
  • http://pusher.com/

正如其他人所提到的,您可以使用AJAX通过setInterval(首选)或setTimeout方法进行轮询。不要忘记创建一个变量来存储集合[Fn]的ID,以防您(或用户)希望取消它:

var pollID = window.setInterval(function poller(){ getAjaxData(); }, 2000);
if (noUpdate) window.clearInterval(pollID);

最新更新