长轮询还是全双工连接?哪个更好?有什么区别?

3
我正在实现一个带有长轮询的消息系统,以便为我的用户提供实时更新。在这样做的过程中,我注意到一些网站(如Hotmail)也使用xhr请求,但它们似乎与我实现的请求略有不同。
如图所示,在我的实现中,客户端发出请求,服务器保持请求直到有新数据更新可用。然后发送有效负载并关闭连接。一旦接收到,JavaScript会向Web服务器发送新请求。
相反,Hotmail在保持连接打开的同时将请求发送回来。这是怎么做到的?我该如何自己实现这个功能?最重要的是,有什么区别?
谢谢。

Long-poll

3个回答

2
有两种最常见的双向HTTP机制,详见RFC6202 "已知问题和最佳实践:在双向HTTP中使用长轮询和流式传输"
  • HTTP长轮询:服务器尝试“保持打开”(不立即回复)每个HTTP请求,只有在有事件要传递时才会响应。通过这种方式,始终存在一个挂起的请求,服务器可以回复该请求以便在事件发生时传递事件,从而最小化消息传递的延迟。

  • HTTP流式传输:服务器无限期地保持请求打开;也就是说,在向客户端推送数据后,它永远不会终止请求或关闭连接。

您还可以在RFC6202中找到这些方法的详细问题列表。每种方法都有其优缺点。

因此,在HTTP流传输期间,连接不会被终止:

使用HTTP流的应用程序的基本生命周期如下:
  1. 客户端发出初始请求,然后等待响应。
  2. 服务器将响应推迟到轮询请求,直到有更新可用,或者直到发生特定状态或超时。
  3. 每当有更新可用时,服务器将其作为响应的一部分发送回客户端。
  4. 服务器发送的数据不会终止请求或连接。服务器返回到步骤3。

2
Hotmail使用Web sockets。Web sockets请求与HTTP请求不同,因为Web socket连接始终保持持久性,而用户在网站上时。因此,通信简要如下:用户第一次打开您的网站时,他向您的服务器发送HTTP请求。由于HTTP协议在OSI模型的第7层,请求通过TCP层并建立套接字连接(位于OSI模型的第5层)与服务器。使用适当的服务器端Web sockets技术,服务器可以使用此持久套接字连接与客户端进行数据推送。
根据您使用的后端语言不同,您可以使用几种不同的技术/库来实现Web套接字。对于asp.net Web应用程序,您可以使用Microsoft的SignalR。如果您使用javascript(Node.js)作为后端,则可以使用Socket.io。请注意,即使您没有使用node.js作为后端,也可以使用Socket.io,但是实现可能不太简单,因为现在您将拥有两个不同的服务器,这些服务器可能需要共享数据(例如:会话或数据库)。
Node.js和SignalR的好处在于它们非常高效,并且可以很好地扩展到许多用户,尤其是Node.js。这两种技术的另一个重要特点是,如果客户端的浏览器不支持Web套接字,则它们具有适当的回退方法,例如服务器发送事件、Ajax轮询、Ajax长轮询、隐藏的iframe元素等。
如需进一步阅读,我建议查看此Stackoverflow问题

我选择这个因为它大多回答了我的问题。我正在实现一个聊天消息系统。到目前为止,长轮询已经非常完美地工作了。但是这让我想出了一个更好的想法。实时“打字”,可以显示用户是否正在输入。因此,我认为Web套接字会是更好的解决方案。我是对的吗? - franks
是的,Web Sockets是您情况下的最佳解决方案。事实上,去年我为我的一个大学项目实现了类似Skype的Web应用程序。基本上,它是一个PHP / MySQL网站,具有所有基本功能,如呈现网站和访问数据库,但我还实现了使用socket.io的node.js服务器,以进行实时更新。基本上,我拥有具有实时消息和输入功能的聊天,但我还进一步实现了WebRTC,以便进行点对点音频/视频通信。如果您想要,我可以在GitHub上上传此项目。 - Dejan Bogatinovski
太棒了!谢谢。目前我更喜欢使用 Facebook 风格的实时聊天,因为这会给我的项目增加太多负担...不过表情符号会有所帮助。 - franks

1

我认为使用长轮询可能有更好的方法。您可以实现WebSocket连接。然后,您将拥有一条持久的、双向的连接到服务器。WebSocket是一个基于HTTP的升级协议,旨在避免像长轮询这样的“折中解决方案”技巧。

如果您想更详细地了解此内容:

https://www.rfc-editor.org/rfc/rfc6455

http://www.html5rocks.com/en/tutorials/websockets/basics/

如果您想支持无法建立WebSockets的旧浏览器,可以使用类似Dojox/Socket的东西,它会自动使用长轮询作为备用。

http://dojotoolkit.org/api/1.10/dojox/socket.html

https://www.sitepen.com/blog/2012/11/05/dojo-websocket-with-amd/


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接