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


1046

我已经尝试阅读一些文章,但是我对这些概念还不太清楚。

有人想向我解释一下这些技术是什么吗?

  1. 长轮询
  2. 服务器发送的事件
  3. 网络套接字
  4. 彗星

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

现在,我应该为实时应用程序使用哪一个。我已经听到很多关于websockets的信息(使用socket.io [一个node.js库]),但是为什么不使用PHP?


1
实时websocket或webrtc?在php中有一个用于websocket的库,您确实需要编写额外的代码才能使其使用ZMQ或仅进行套接字编程,nodeJs就是为此而构建的,因此很容易获得。websocket在php中不可用的原因是,您必须运行一个额外的终端并使它保持运行状态,以便websocket服务器随时可用,您将拥有两台服务器。并且该结构php不是像javascript这样的事件结构,因此,websocket使用事件结构来捕获和发送消息。
PauAI”

另外:Comet和ServerSent Events是PHP的变通方法,可在不创建2个服务器的情况下实现几乎实时(不是真的)。
PauAI'4

Answers:


2075

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

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

常规HTTP:

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

HTTP

Ajax轮询:

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

Ajax轮询

Ajax长轮询:

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

Ajax长轮询

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

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

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


21
这太棒了!我正在阅读SSE,发现这篇文章非常好-就像我现在比较的东西一样,您是否也可以在这里包含SSE,以便我们也可以交叉检查它与Websocket的区别?
编制索引

1
@Tieme哦,是吗?我以为SSE意味着服务器发送事件。无论如何,谢谢,我现在看到了。
索引

1
问:在php中,假设您使用的是websocket,是否每个客户端都使用ws连接到我的服务器:是否将一个线程分配给他/她,并且其大小将约为2mb(与普通请求一样)?nodejs有什么不同?nodejs可以处理多少个并发客户端,何时中断会发生什么?
穆罕默德·乌默尔

5
两种解决方案都可以完成相同的工作,但是机制不同。长轮询使用“常规” http数据,与长轮询相比,SSE使用不同的基础协议,并且需要不同的服务器设置。
蒂姆,

2
好吧,如果您愿意,可以使用apache。但是很多人使用Node.js,因为它具有事件循环。但对于Apache的,看到stackoverflow.com/questions/12203443/...
Tieme

37

Tieme为他的出色答案付出了很多努力,但是我认为OP问题的核心是这些技术如何与PHP相关联,而不是每种技术如何工作。

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

1)PHP最初是一个非常基本的CGI。从早期开始,PHP就已经取得了长足的进步,但是它发生的步伐很小。到今天PHP成为可嵌入且灵活的C库时,PHP已经拥有数百万用户,其中大多数人都依赖于它的早期执行模型,因此它还没有做出坚定的尝试来逃避PHP。内部cgi模型。甚至命令行界面也会调用PHP库(在Linux上为libphp5.so,在Windows上为php5ts.dll等),就好像它还是处理GET / POST请求的cgi一样。它仍然执行代码,就好像只需要构建一个“页面”,然后结束其生命周期一样。结果,它几乎不支持多线程或事件驱动的编程(在PHP用户空间内),从而使其目前对于实时的多用户应用程序不可行。

请注意,PHP确实具有扩展,可以在PHP用户空间中提供事件循环(例如libevent)和线程(例如pthreads),但是很少有应用程序使用它们。

2)PHP在垃圾回收方面仍然存在重大问题。尽管这些问题一直在不断改善(如上所述,这可能是结束生命周期的最重要的一步),但即使是创建长期运行的PHP应用程序的最佳尝试,也需要定期重新启动。这也使其对于实时应用不切实际。

PHP 7也将是解决这些问题的重要一步,并且作为用于实时应用程序的平台似乎很有希望。


2
一个小小的修正:PHP总是用C编写的,如此处所示:museum.php.net/php1另外,“使用较少(但更流行)的是自相矛盾的。也许您的意思是“更时尚”?
IMSoP 2014年

@IMSoP-感谢您的更正,我使用PHP已有十多年了,一直给人一种印象,它的根源是Perl。PHP 历史记录页面明确支持它也最初是C。我一会儿就会编辑答案。
JSON

我将删除有关Perl的内容,因为它不能与官方文档很好地融合在一起,但这在PHP的早期开发中仍然是一个令人困惑的领域。
JSON

PHP 7作为实时应用程序平台看起来非常有前途吗?PHP7对实时应用程序有哪些改进/变化?
我将



By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.