【问题标题】:Web Page update without polling无需轮询的网页更新
【发布时间】:2014-01-08 11:27:50
【问题描述】:

我正在开发一个网络应用程序,用户可以在其中请求服务,并且提供者可以响应他。因此,当用户请求某种服务时,我们的应用程序将向提供者发送通知(要求他响应用户)。 我想做的是:当用户请求服务时,提供者会立即收到通知(就像 facebook 一样)。

实现此目的的一种方法是使用 AJAX 每 5-10 秒向服务器发送一次请求;我们称之为轮询(到目前为止我知道)。但是,这种方法有一些缺陷,我明白了:-

  • 由于请求将每 5-10 秒发送一次,因此处理请求和返回空数据(非常频繁)将是服务器的负载。
  • 即使没有任何更新,向服务器发送请求也没有用。
  • 想象一下,在服务器响应请求后,有人请求服务。因此,提供商必须再等待 5-10 秒才能收到有人请求某事的通知。

所以,我想知道是否有某种技术可以在我们的系统发生更改时立即更新我们的网页,而无需使用 AJAX 轮询请求。

【问题讨论】:

  • 听起来你想看看 websockets。我建议开始使用socket.io。不要担心,因为它的节点,有一个服务器规范,你可以用 PHP 构建,你可以简单地使用 socket.io-client
  • 正如@jibsales 所说的一个选项是websockets,另一个选项是修改类型的轮询调用长轮询。我会研究两者,看看哪一个更适合你。
  • 您的另一个可行的 websockets 替代方案是服务器发送事件。 EventSource 是此 API 的 Javascript 包装器。它们的工作方式与 websocket 类似,只是数据仅来自 服务器,不会再返回。当然你可以做一个 Ajax 帖子来再次发回数据...html5rocks.com/en/tutorials/eventsource/basics

标签: javascript php ajax web polling


【解决方案1】:

这是一个使用 php 的简单服务器发送事件脚本。

支持

https://developer.mozilla.org/en-US/docs/Web/API/EventSource

js

var sse=new EventSource("sse.php");
sse.onmessage=function(e){
 document.body.innerHTML=e.data;
};

sse.php

header('Content-Type: text/event-stream'); // specific sse mimetype
header('Cache-Control: no-cache'); // no cache
while(true) {
 if(/*something changes*/){
  echo "id: ".time().PHP_EOL;
  echo "data: ".$data.PHP_EOL;
  echo PHP_EOL;
 }
  ob_flush(); // clear memory
  flush(); // clear memory
  sleep(10);// seconds 
}

这使与客户端的连接保持打开状态,

然后它会检查是否有任何更改... db/file 不管什么

如果发生变化则输出数据

然后清除php缓存

等待 10 秒,然后再做一次。


如您所见,只有在服务器发生变化时,客户端才会收到数据

但我完全不知道服务器如何处理 1000 人。


node.js 会是更好的方法。但这取决于您使用的语言和/或您是否可以实际使用 node.js。

websockets 是双向的。

服务器发送的事件是单向的。(你需要这个)

编辑

sse 响应中的更多数据:

js

var sse=new EventSource("sse.php");
sse.onmessage=function(e){
 console.log(JSON.parse(e.data))
};

sse.php

header('Content-Type: text/event-stream'); // specific sse mimetype
header('Cache-Control: no-cache'); // no cache
while(true) {
 if(/*something changes*/){
  echo "id: ".time().PHP_EOL;

  $dataArray=array('id'=>$id,'name'=>$name,'more'=>$more);
  echo "data: ".json_encode($dataArray).PHP_EOL;

  echo PHP_EOL;

 }
  ob_flush(); // clear memory
  flush(); // clear memory
  sleep(10);// seconds 
}

如果您需要更多信息,请询问

【讨论】:

  • 正如您在上面提到的,它会等待 10 秒以再次重复该过程,所以您真的认为 Server Sent Events 会是一个解决方案吗?我不知道我问的是不是一个好问题。
  • sse 是为您的要求而设计的。但是 php 不是用来流式传输数据的。解决方案肯定比轮询更好。通过将 sleep(10) 更改为 sleep(3) 它每 3 秒重复一次该过程..
  • 我肯定会尝试 SSE 和 websockets。还有一个问题,如果从 php 脚本中删除 sleep() 函数,如果我在调用脚本时需要发送一些参数(如用户 ID 或其他东西)怎么办?
  • 如果你删除 sleep() 服务器崩溃。 3 秒的速度足以得到响应。否则将其更改为 1-2... 数据可以包含一个字符串。因此,如果您想添加额外的数据,请将其转换为 json。我添加示例。
  • 我要试试这个,投票给你。很快就会提出问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-12
  • 2022-01-20
  • 2017-10-26
相关资源
最近更新 更多