【问题标题】:What is the least invasive way of checking for server side updates检查服务器端更新的侵入性最小的方法是什么
【发布时间】:2016-11-20 14:30:06
【问题描述】:

我有一个使用 javascript xmlhttprequest 连接到 PHP 脚本的 Web 应用程序 我正在尝试检查服务器端何时发生变化。 我只能通过每秒向页面发送一个 ping 来检查

javascript

function stayConnected(){
  setTimeout(function(){
    xmlhttp.send();
  },1000);
}

php

<?php
  if(update())echo "there's an update";
  flush();
?>

这对用户和服务器来说是超级密集的

这样更好吗

javascript

xmlhttp.onreadystatechange = function(){
  if(server.xml.readyState == 4 &&
    server.xml.status == 200){
    doSomething(xmlhttp.responseText);
    xmlhttp.send();
  }
}

php

<?php
  for( $i = 0; i < 120; i++){
    if(update()){
      echo "there's and update";
      break;
    }
    sleep(1000);
  }
  flush();
?>

第二种解决方案对查看者来说似乎更好,但它会伤害服务器吗? 我无法很好地检查服务器负载。有没有更好的解决方案?

【问题讨论】:

  • 第二个例子不循环

标签: javascript php optimization xmlhttprequest


【解决方案1】:

这是我之前回答from this board的转载。

您可以使用服务器发送事件。流程如下:

  1. 每个用户订阅一个频道(将其视为在连接上注册一个事件监听器)。在服务器端,脚本会持续运行以跟踪更改
  2. 用户向服务器发布更新。
  3. 脚本注意到更新并发出事件
  4. 订阅频道的所有客户端都会收到该事件,读取其data 属性并更新其本地模型。

请参阅this introduction,以及示例 PHP 实现。

您也可以使用 Web Sockets。这是comparison of the two。在实施之前,请考虑browser compatibility

【讨论】:

    【解决方案2】:

    您有多种选择:

    轮询

    这是您提到的第一个选项。客户端必须每隔 x 个时间单位请求一次更新。这会导致许多请求。想想每秒有 100 个用户请求更新,这导致每分钟有 6000 个请求。在许多情况下,请求会排队,不再是实时的。

    长轮询

    这里客户端发送一个请求,在服务器上你有一个检查更新的循环(有点像你的第二个例子)。一旦有更新,就会发送响应。这会导致 许多并行线程 为服务器处理。 100 个用户产生 100 个线程……

    两种解决方案都不是最优的。相反,我们应该使用持久连接进行通信。

    持久连接有两种选择:

    网络套接字

    WebSockets 提供客户端和服务器之间的持久连接,双方可以使用它随时开始发送数据。最后这是一个事件循环,但你不必关心这个。优点是,这是另一种专门用于实时连接的协议! WebSockets 是基于事件的,所以它只使用一个线程。

    服务器发送事件

    它与 WebSockets 非常相似。您在客户端打开到服务器的持久连接,但通过 HTTP。主要区别在于 SSE 连接只能向客户端推送数据。

    结论

    所以在实践中:由于可以使用 SSE 完成的所有操作也可以使用 WebSockets 完成,并且浏览器对 WebSockets 的支持比对 SSE 的支持要好得多,我认为这是您可以做到的最佳选择一起去。 例如:IE/Edge 支持 WebSockets 但不支持 SSE

    也许您可以使用 Ratchet 作为 PHP 的 WebSockets 框架: http://socketo.me/

    但我必须给你一个提示,PHP 不是为大量实时应用程序而设计的。这就是您的用例,也许您应该使用 node.js 作为后端,因为 JavaScript 天生就是基于事件的以适应这种用例。

    【讨论】:

    • 您的回答非常好。我已标记为正确答案,但我无权访问服务器管理员权限,因此我无法使用 Web 套接字。 SSE 是唯一的其他解决方案吗? IE 有什么代替吗?
    • 如果你想要所有市长浏览器的支持,我也会考虑使用长轮询。像 Comet 这样的著名框架正在使用长轮询,它们工作得非常好。许多框架也使用长轮询作为 websockets 的后备(例如 socket.io)。对于实施,可以看看:stackoverflow.com/questions/333664/…
    • 您还可以做的是检查客户端是否支持服务器发送事件,如果支持,则仅在客户端不支持 SSE 时使用此和长轮询作为后备。
    猜你喜欢
    • 2010-10-05
    • 2011-03-16
    • 1970-01-01
    • 1970-01-01
    • 2013-07-08
    • 1970-01-01
    • 1970-01-01
    • 2011-01-19
    • 1970-01-01
    相关资源
    最近更新 更多