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

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

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

Http长轮询: AJAX,但服务器坚持的响应,除非服务器有更新,一旦服务器有更新,它发送它,然后客户端可以发送另一个请求。 缺点是额外的头数据需要来回发送,造成额外的开销。

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

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

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

  • WebSockets相对于Java Applets,Flash或Silverlight等插件的唯一优势在于,WebSockets本身就内置于浏览器中,不依赖于插件。
  • WebSocket相对于HTTPstream的唯一优势是您不必花费精力来理解和parsing接收到的数据。
  • 通过长轮询的WebSocket的唯一优点是消除额外的头大小和打开和closures请求的套接字连接。

还有什么其他重要的差异,我失踪了? 我很抱歉,如果我重复询问或将已经存在的许多问题合并成一个单一的问题,但我只想从所有关于这些概念的Web和Web上的信息中完全理解。

谢谢!

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

双面打印/方向:

  • 单向:HTTP轮询,长轮询,stream媒体。
  • Bi-direcitonal:WebSockets,插件networking

按递增的等级(近似):

  • 的WebSockets
  • 插件networking
  • HTTPstream媒体
  • HTTP长时间轮询
  • HTTP轮询

CORS(跨源支持):

  • WebSockets:是的
  • 插件联网:通过策略请求闪光灯(不知道其他人)
  • HTTP *(最近的一些支持)

本机二进制数据(键入数组,blob):

  • WebSockets:是的
  • 插件networking:不使用Flash(需要通过ExternalInterface进行URL编码)
  • HTTP *:最近提出启用二进制types支持

带宽降低效率:

  • 插件networking:除最初的策略请求外,Flash套接字是原始的
  • WebSockets:连接build立握手和每帧几个字节
  • HTTPstream式传输(重新使用服务器连接)
  • HTTP长轮询:连接每个消息
  • HTTP轮询:连接每个消息+没有数据消息

移动设备支持:

  • WebSocket:iOS 4.2及更高版本。 某些Android通过Flash模拟,或者使用Android版Firefox或Android版 Google Chrome ,都提供本地WebSocket支持。
  • 插件联网:一些Android。 不在iOS上
  • HTTP *:大部分是

Javascript的使用复杂性(从最简单到最复杂)。 无可否认,复杂性措施有些主观。

  • 的WebSockets
  • HTTP轮询
  • 插件networking
  • HTTP长轮询,stream媒体

另外请注意,有一个W3C提议标准化HTTPstream,称为服务器发送事件 。 它目前还处于演化的早期阶段,旨在为WebSockets提供一个标准的JavaScript API。

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

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

如果通过这个,你的意思是你可以使用Java Applets,Flash或者Silverlightbuild立套接字连接,那么是的,这是可能的。 但是由于这种限制,你不会看到在现实世界中部署的太多。

例如,中介可以并且closures那个stream量。 WebSocket标准被devise为与现有的HTTP基础设施兼容,因此不太容易被诸如防火墙和代理之类的中介干扰。

此外,WebSocket可以使用端口80和443而不需要专用端口,这要归功于协议devise与现有HTTP基础结构尽可能的兼容。

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

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

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

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

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

虽然对于这些情况的某种回退策略是明智的,甚至是必要的,但是大多数使用Flash等的策略将会遭受上述缺点。 它不一定是这样 – 有解决方法来实现使用Flash,Silverlight等安全的跨源连接 – 但大多数实现不会这么做,因为这并不容易。

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

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

WebSocket相对于HTTPstream的唯一优势是您不必花费精力来理解和parsing接收到的数据。

这并不像打开HTTPstream那样简单,而是随着数据stream过几分钟,几小时甚至更长时间。 不同的客户不同的行为,你必须pipe理。 例如,一些客户端将缓冲数据,并不会将其释放到应用程序,直到达到某个阈值。 更糟糕的是,在连接closures之前,有些人不会将数据传递给应用程序。

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

当WebSocket不可用时,HTTPstream可以成为一个可行的select,但它不是万能的。 在现实世界的条件下,它需要一个很好的理解,在networking的荒地上以一种强有力的方式工作。

还有什么其他重要的差异,我失踪了?

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

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

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

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

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

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

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

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

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

如果我可能会问一个额外的事情:我遇到了一个文章的地方说,HTTPstream可能也被代理caching,而WebSockets没有。 那是什么意思?

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

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

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

所以客户#1请求http://example.comhttp://img.dovov.comlogo.gif ,说。 该请求通过代理一直到中央Web服务器,它提供了logo.gif。 当logo.gif通过代理时,代理将保存该图像并将其与地址http://example.comhttp://img.dovov.comlogo.gif相关联。;

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

在web服务器上更新logo.gif时出现问题。 代理将继续服务旧的图像不知道有一个新的形象。 这会导致整个事情到期,所以代理只会在“expires”之前的一小段时间caching图像,下一个请求通过代理到达Web服务器,然后刷新代理的caching。 还有更高级的解决scheme,中央服务器可以推送到已知的caching等等,事情可以变得非常复杂。

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

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

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

所以,如果你的客户提出了股票价格的请求,并得到了回应,那么下一个客户可能会提出相同的请求并获得caching的数据。 可能不是你想要的! 如果你要求股票价格,你想要最新的数据,对不对?

所以这是一个问题。

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

HTTP将客户端与服务器的连接数限制为2(尽pipe这可以通过使用子域来缓解),并且IE已经知道强制实施这一点。 火狐和Chrome允许更多(虽然我不记得我的头顶多less)。 这似乎不是一个大问题,但是如果您不断地使用1个连接进行实时更新,则所有其他请求都必须通过其他HTTP连接进行瓶颈。 而且有更多的客户端的开放连接会给服务器带来更多的负担。

WebSocket是基于TCP的协议,因此不会受到HTTP级连接限制(但是,当然,浏览器支持是不统一的)。