什么是长轮询,Websockets,服务器发送事件(SSE)和Comet?

use*_*328 1005 php comet long-polling websocket server-sent-events

我曾尝试阅读一些文章,但我对这些概念还不是很清楚.

有人愿意尝试向我解释这些技术是什么:

  1. 长轮询
  2. 服务器发送的事件
  3. 的WebSockets
  4. 彗星

我每次遇到的一件事是,服务器保持连接打开并将数据推送到客户端.如何保持连接打开,客户端如何获取推送数据?(客户端如何使用数据,也许某些代码可能会有帮助?)

现在,我应该将其中哪一个用于实时应用.我一直听说很多关于websockets(有socket.io [一个node.js库]),但为什么不用PHP?

Tie*_*eme 2032

在下面的示例中,客户端是浏览器,服务器是托管网站的Web服务器.

在了解这些技术之前,您必须首先了解经典的 HTTP Web流量.

常规HTTP:

  1. 客户端从服务器请求网页.
  2. 服务器计算响应
  3. 服务器将响应发送给客户端.

HTTP

Ajax轮询:

  1. 客户端使用常规HTTP从服务器请求网页(请参阅上面的HTTP).
  2. 客户端接收所请求的网页并在页面上执行JavaScript,该JavaScript以规则的间隔(例如0.5秒)从服务器请求文件.
  3. 服务器计算每个响应并将其发回,就像普通的HTTP流量一样.

Ajax Polling

Ajax Long-Polling:

  1. 客户端使用常规HTTP从服务器请求网页(请参阅上面的HTTP).
  2. 客户端接收请求的网页并在页面上执行JavaScript,该页面从服务器请求文件.
  3. 服务器不会立即响应所请求的信息,而是等待有信息可用.
  4. 当有新信息可用时,服务器会使用新信息进行响应.
  5. 客户端接收新信息并立即向服务器发送另一个请求,重新启动该过程.

Ajax Long-Polling

HTML5服务器发送事件(SSE)/ EventSource:

  1. 客户端使用常规HTTP从服务器请求网页(请参阅上面的HTTP).
  2. 客户端接收请求的网页并在页面上执行JavaScript,该页面打开与服务器的连接.
  3. 当有新信息可用时,服务器会向客户端发送事件.

    • 从服务器到客户端的实时流量,大部分都是您需要的
    • 您将需要使用具有事件循环的服务器
    • 只有正确的CORS设置才能与来自其他域的服务器建立连接
    • 如果你想阅读更多,我发现这些非常有用:( 文章),(文章),(文章),(教程).

HTML5 SSE

HTML5 Websockets:

  1. 客户端使用常规http从服务器请求网页(请参阅上面的HTTP).
  2. 客户端接收请求的网页并在页面上执行JavaScript以打开与服务器的连接.
  3. 现在,当新数据(在任一侧)可用时,服务器和客户端可以相互发送消息.

    • 从服务器到客户端以及从客户端到服务器的实时流量
    • 您将需要使用具有事件循环的服务器
    • 使用WebSockets,可以从另一个域连接服务器.
    • 也可以使用第三方托管的websocket服务器,例如Pusher其他服务器.这样你只需要实现客户端,这很容易!
    • 如果你想阅读更多,我发现这些非常有用:( 文章),(文章)(教程).

HTML5 WebSockets

彗星:

Comet是HTML5之前的一系列技术,它们使用流式传输和长轮询来实现实时应用.了解更多关于维基百科文章.


现在,我应该将它们中的哪一个用于实时应用程序(我需要编写代码).我一直听说很多关于websockets(有socket.io [一个node.js库]),但为什么不用PHP?

您可以将PHP与WebSockets一起使用,请查看Ratchet.

  • 这太棒了!我正在读SSE并发现这篇文章,它非常好 - 就像我现在比较的东西一样,你是否也可以在这里包含SSE所以我们也可以交叉检查它与Websocket的区别? (19认同)
  • 您可以使用两种解决方案完成相同的操作,但机制不同.长轮询使用"常规"http数据,SSE使用不同的底层协议,与长轮询相比需要不同的服务器设置. (5认同)
  • 好吧,如果你愿意,你可以使用apache.但是很多人使用Node.js因为它有一个事件循环.但是对于Apache,请参阅http://stackoverflow.com/questions/12203443/is-native-php-support-for-web-sockets-available#12204603 (2认同)
  • @Tieme 我知道 2013 年已经是很久以前的事了,但我想指出 SSE 没有使用不同的协议。我只是 HTTP 分块编码的一种变体,浏览器通过在套接字上设置 TCP keepalive 来适应它。与 websocket 不同,它也适用于 HTTP/2。 (2认同)

JSO*_*SON 36

Tieme在他的优秀答案中投入了大量精力,但我认为OP问题的核心是这些技术与PHP的关系,而不是每种技术的工作原理.

除了明显的客户端html,css和javascript之外,PHP是Web开发中使用最多的语言.然而,PHP在实时应用程序方面有两个主要问题:

1)PHP作为一个非常基本的CGI开始.自从早期阶段开始,PHP已经取得了很大进展,但它只是小步骤发生的.当PHP成为今天的嵌入式和灵活的C库时,PHP已经拥有数百万用户,其中大多数用户依赖于它早期的执行模式,所以它还没有做出明确的尝试来逃避内部的cgi模型.甚至命令行界面也会调用PHP库(linux上的libphp5.so,windows上的php5ts.dll等),好像它仍然是一个处理GET/POST请求的cgi.它仍然执行代码,好像它只需要构建一个"页面"然后结束它的生命周期.因此,它几乎不支持多线程或事件驱动的编程(在PHP用户空间内),这使得它对于实时的多用户应用程序来说当前不实用.

请注意,PHP确实具有在PHP用户空间中提供事件循环(例如libevent)和线程(例如pthreads)的扩展,但非常非常少的应用程序使用这些.

2)PHP仍然存在垃圾收集的重大问题.虽然这些问题一直在不断改进(可能是结束生命周期的最大步骤,如上所述),但即使是创建长期运行的PHP应用程序的最佳尝试也需要定期重新启动.这也使得它对于实时应用程序来说不实用.

PHP 7将是解决这些问题的重要一步,并且作为实时应用程序的平台似乎非常有前途.

  • 一个小的更正:PHP 总是用 C 编写,可以在这里看到:http://museum.php.net/php1/ 另外,“较少使用(但非常流行)”是相当自相矛盾的;也许你的意思是“更时尚”? (2认同)

Gun*_*jan 13

轮询

基本上,轮询是一种定期向服务器请求信息的技术。此连接通过遵循 HTTP 协议进行。有两种类型的轮询:

  1. 短轮询
  2. 长轮询

短轮询

简而言之,轮询是客户端向服务器请求信息。服务器处理请求。如果数据可用于请求,服务器将使用所需信息响应请求。但是,如果服务器没有可供客户端使用的数据,则服务器将返回空响应。在这两种情况下,连接都会在返回响应后关闭。即使服务器发送空响应后,客户端仍会不断发出新请求。这种机制增加了服务器上的网络成本。

长轮询

在长轮询中,客户端可以向服务器请求信息,但期望服务器可能不会立即响应。当服务器收到请求时,如果没有为客户端提供新鲜数据,服务器不会返回空响​​应,而是保持请求打开并等待数据到达。当服务器收到新数据时,立即将响应传递给客户端,完成打开请求。在从服务器获得答案后,​​客户端可以发送另一个新更新请求。长轮询通过减少空响应的数量来降低成本。

WebSocket

WebSocket 是一种通过单个 TCP 连接提供双向(双向)通信通道的协议。Websocket 促进了客户端和服务器之间的持久连接,允许双方随时开始传输数据。WebSocket 握手是客户端创建 WebSocket 连接的过程。如果操作成功,服务器和客户端就可以随时发送和接收数据。主要用于实时网络应用程序,例如 WhatsApp、Uber。

服务器发送的事件 (SSE)

与 WebSocket 不同,我们无法使用 SSE 从客户端向服务器发出请求,因为它是一种单向连接。当我们需要从服务器到客户端的“近实时”传输,或者服务器循环生成数据时,SSE是理想的选择。

彗星

Comet 是一种 Web 应用程序设计范例,它描述了使用本机 HTTP 方法在服务器和 Web 浏览器之间进行连续的双向交互。彗星是一个总称。Ajax Push、HTTP Streaming 和 HTTP Server Push 是可用于提供这种事件驱动交互的一些 HTTP 机制。


Joh*_*ohn 9

我试图记下这些,并从java角度收集和编写示例.

适用于Java开发人员的HTTP

反向Ajax - 旧式

服务器端的异步处理

反向Ajax - 新风格

服务器已发送事件

将它放在任何正在研究相同主题的java开发人员.