我对HTTP轮询,长轮询,HTTP流和WebSockets的理解

我在SO和网上阅读了很多关于我的问题标题中关键字的帖子,并从中学到了很多。 我读到的一些问题与具体的实施挑战有关,而另一些则关注一般概念。 我只想确保我理解了为什么技术X是相对于技术Y而言发明的所有概念和理由。 所以在这里:

Http轮询:基本上是AJAX,使用XmlHttpRequest。

Http Long Polling: AJAX,但服务器保留响应,除非服务器有更新,只要服务器有更新,它就发送它,然后客户端可以发送另一个请求。 缺点是需要来回发送附加头数据,导致额外开销。

Http Streaming:类似于长轮询,但服务器以“Transfer Encoding:chunked”的头部响应,因此我们不需要在每次服务器发送一些数据(并因此保存额外的头部开销)时发起新的请求。 这里的缺点是我们必须“理解”并找出数据的结构来区分服务器发送的多个块。

Java Applet,Flash和Silverlight:它们提供了通过tcp / ip连接套接字服务器的能力,但由于它们是插件,因此开发人员不希望依赖它们。

WebSockets:它们是以下列方式尝试解决上述方法短缺的新API:

  • WebSockets相对于Java Applets,Flash或Silverlight等插件的唯一优势在于WebSocket本身嵌入到浏览器中,并且不依赖于插件。
  • WebSockets相对于HTTP流的唯一优势在于,您无需努力“理解”并解析收到的数据。
  • 通过长轮询的WebSockets的唯一优点是消除额外的头大小和打开和关闭请求的套接字连接。
  • 我还有其他重大差异吗? 我很抱歉,如果我重新询问或将已经存在的许多问题合并成一个问题,但我只想从SO和网络上关于这些概念的所有信息中完全理解。

    谢谢!


    有比你确定的更多的差异。

    双面打印/方向:

  • 单向:HTTP轮询,长轮询,流媒体。
  • Bi-direcitonal:WebSockets,插件网络
  • 按延迟递增(近似):

  • 的WebSockets
  • 插件网络
  • HTTP流媒体
  • HTTP长时间轮询
  • HTTP轮询
  • CORS(跨源支持):

  • WebSockets:是的
  • 插件网络:Flash通过策略请求(不确定其他人)
  • HTTP *(最近的一些支持)
  • 本机二进制数据(键入数组,blob):

  • WebSockets:是的
  • 插件网络:不适用于Flash(需要通过ExternalInterface进行URL编码)
  • HTTP *:最近提议启用二进制类型支持
  • 降低效率的带宽:

  • 插件网络:除最初的策略请求外,Flash套接字是纯粹的
  • WebSockets:连接建立握手和每帧几个字节
  • HTTP流式传输(重新使用服务器连接)
  • HTTP长轮询:每条消息的连接
  • HTTP轮询:连接每个消息+没有数据消息
  • 移动设备支持:

  • WebSocket:iOS 4.2及更高版本。 一些Android通过Flash模拟,或者使用Firefox for Android或Google Chrome for Android,它们都提供本机WebSocket支持。
  • 插件网络:一些Android。 不在iOS上
  • HTTP *:大部分是
  • Javascript的使用复杂性(从最简单到最复杂)。 无可否认,复杂性措施有些主观。

  • 的WebSockets
  • HTTP轮询
  • 插件网络
  • HTTP长轮询,流媒体
  • 另外请注意,有一个W3C提议标准化HTTP流,称为Server-Sent Events。 它目前还处于演化的早期阶段,旨在提供一个标准的JavaScript API,与WebSockets相媲美。


    来自其他人的一些很好的答案涵盖了很多理由。 这里有一点额外的。

    WebSockets相对于Java Applets,Flash或Silverlight等插件的唯一优势在于WebSocket本身嵌入到浏览器中,并且不依赖于插件。

    如果你认为你可以使用Java Applets,Flash或Silverlight建立套接字连接,那么是的,这是可能的。 但是由于限制,你不会看到经常部署在真实世界中。

    例如,中介可以并关闭该流量。 WebSocket标准被设计为与现有的HTTP基础设施兼容,因此不容易受到诸如防火墙和代理之类的中介干扰。

    而且,WebSocket可以使用端口80和443而不需要专用端口,这要归功于协议设计尽可能与现有的HTTP基础设施兼容。

    这些套接字替代品(Java,Flash和Silverlight)难以在跨源架构中安全使用。 因此,人们经常尝试将它们用于交叉来源将容忍这种不安全感,而不是去做安全的努力。

    他们还可能需要打开额外的“非标准”端口(管理员不愿意这么做)或需要管理的策略文件。

    简而言之,使用Java,Flash或Silverlight进行套接字连接的问题已经足够,以至于您看不到它经常部署在严重的体系结构中。 Flash和Java已经具备了这种功能,至少可以使用10年,但它并不普遍。

    WebSocket标准能够以全新的方式开始,考虑到这些限制,并希望从中吸取一些教训。

    当WebSocket连接无法建立时(例如,在旧浏览器中运行或中介干扰时),一些WebSocket实现使用Flash(或可能使用Silverlight和/或Java)作为它们的后备。

    尽管针对这些情况的某种回退策略是明智的,甚至是必要的,但大多数使用Flash等的策略都会遇到上述缺陷。 它不一定是这样的 - 有一些解决方法可以实现使用Flash,Silverlight等安全的支持跨源的连接 - 但大多数实现不会那么做,因为这并不容易。

    例如,如果您依靠WebSocket进行跨源连接,那么这将工作正常。 但是,如果您在旧浏览器或防火墙/代理中运行,并且依赖于Flash,那么作为您的后备,您会发现很难做到同样的跨源连接。 当然,除非你不关心安全性。

    这意味着很难有一个统一的架构适用于本地和非本地连接,除非您准备投入相当多的工作或者使用一个已经完成的框架。 在一个理想的架构中,你不会注意到这些连接是否是本地的; 您的安全设置可以在两种情况下使用; 您的群集设置仍然有效; 您的容量规划仍然存在; 等等。

    WebSockets相对于HTTP流的唯一优势在于,您无需努力“理解”并解析收到的数据。

    这不像打开HTTP流那样简单,并且随着数据流过几分钟,几小时或更长时间就会回来。 不同的客户端行为不同,你必须管理它。 例如,有些客户端会缓冲数据,而不会将其释放到应用程序,直到达到某个阈值。 更糟糕的是,有些人在连接关闭之前不会将数据传递给应用程序。

    因此,如果您要将多条消息发送到客户端,则例如,客户端应用程序可能会收到数据,直到收到50条消息的数据为止。 这不是太实时。

    当WebSocket不可用时,HTTP流传输可以成为可行的替代方案,但它不是万能的。 在真实世界的情况下,它需要很好的理解才能在网络的恶劣环境中以稳健的方式工作。

    我还有其他重大差异吗?

    还有一件事还没有人提到,所以我会提出来。

    WebSocket协议被设计成为更高级别协议的传输层。 虽然您可以发送JSON消息或什么 - 而不是直接通过WebSocket连接,它也可以携带标准或自定义协议。

    例如,你可以通过WebSocket完成AMQP或XMPP,就像人们已经完成的那样。 因此,客户可以从AMQP代理接收消息,就好像它直接连接到代理本身(在某些情况下)。

    或者,如果您有一个现有的服务器和一些自定义协议,则可以通过WebSocket传输它,从而将该后端服务器扩展到Web。 通常,已经锁定在企业中的现有应用程序可以扩大使用WebSocket的范围,而无需更改任何后端基础架构。

    (当然,你希望能够安全地做到这一点,所以请与供应商或WebSocket提供商联系。)

    有些人把WebSocket称为Web的TCP。 因为就像TCP传输更高级别的协议一样,WebSocket也是如此,但与Web基础结构兼容。

    因此,尽管通过WebSocket直接发送JSON(或其他)消息总是可能的,但也应该考虑现有的协议。 因为对于你想要做的很多事情,可能有一个协议已经被认为可以做到。

    我很抱歉,如果我重新询问或将已经存在的许多问题合并成一个问题,但我只想从SO和网络上关于这些概念的所有信息中完全理解。

    这是一个很好的问题,答案都非常丰富!


    如果我可能会问一个额外的事情:我在某个地方发现了一个文章,它说http流可能也会被代理缓存,而websocket则不会。 那是什么意思?

    (StackOverflow限制评论回复的大小,所以我不得不在这里回答,而不是内联。)

    那是个很好的观点。 要理解这一点,请考虑传统的HTTP场景......想象一下,浏览器打开了一个网页,所以它请求http://example.com。 服务器用包含该页面的HTML的HTTP进行响应。 然后浏览器看到页面中有资源,所以它开始请求CSS文件,JavaScript文件和图像。 它们都是静态文件,对于所有请求它们的客户端都是相同的。

    某些代理会缓存静态资源,以便来自其他客户端的后续请求可以从代理获取这些静态资源,而不必一直回到中央Web服务器以获取它们。 这是缓存,从您的中央服务卸载请求和处理是一个很好的策略。

    因此,客户#1请求http://example.com/images/logo.gif。 该请求会通过代理一直到中央Web服务器,该服务器会提供logo.gif。 当logo.gif通过代理时,代理将保存该图像并将其与http://example.com/images/logo.gif地址相关联。

    当客户端#2出现并且还请求http://example.com/images/logo.gif时,代理可以返回图像,并且不需要通信回到中心的网络服务器。 这给最终用户提供了更快的响应,这总是很棒,但这也意味着中心的负载较低。 这可以转化为降低硬件成本,降低网络成本等等。所以这是一件好事。

    在Web服务器上更新logo.gif时出现问题。 代理将继续为旧图像提供服务,但不知道有新图像。 这会导致整个过程到期,因此代理只会在“过期”之前将图像缓存一小段时间,并且下一个请求会通过代理传递给Web服务器,然后Web服务器会刷新代理的缓存。 还有更高级的解决方案,中央服务器可以推送到已知的缓存等等,而且事情可以变得非常复杂。

    这与你的问题有什么关系?

    您询问了HTTP服务器将HTTP流式传输到客户端的情况。 但是,流传输HTTP就像普通的HTTP一样,除非您不停止发送数据。 如果Web服务器提供图像,它会将HTTP发送到最终结束的客户端:您发送了整个图像。 如果你想发送数据,它是完全一样的,但服务器只是发送一个很长的时间(比如它是一个庞大的巨大图像),甚至永远不会完成。

    从代理的角度来看,它不能区分静态资源(如图像)的HTTP或HTTP流的数据。 在这两种情况下,客户端都提出了服务器请求。 代理人记得该请求以及回复。 下一次请求进入时,代理服务器会提供相同的响应。

    因此,如果您的客户提出股票价格请求并获得响应,则下一个客户端可能会发出相同的请求并获取缓存的数据。 可能不是你想要的! 如果你要求股票价格,你想要最新的数据,对吧?

    所以这是一个问题。

    有技巧和解决方法来处理这样的问题,这是事实。 很明显,你可以让HTTP流式传输工作,因为它现在正在使用。 这对于最终用户来说都是透明的,但是开发和维护这些架构的人们必须跳过这些环节并付出代价。 这会导致过度复杂的体系结构,这意味着更多的维护,更多的硬件,更多的复杂性,更多的成本。 这也意味着开发人员经常不得不关注他们应该只关注应用程序,GUI和业务逻辑时不应该做的事情 - 他们不应该关心底层通信。

    链接地址: http://www.djcxy.com/p/44695.html

    上一篇: My Understanding of HTTP Polling, Long Polling, HTTP Streaming and WebSockets

    下一篇: HTML5 Web socket Handshaking