我在SO和网页上阅读了很多关于我的问题标题中关键字的帖子,并从中学到了很多。我读到的一些问题与具体的实施挑战有关,而其他问题则侧重于一般概念。我只是想确保我理解为什么技术X是在技术Y上发明的所有概念和原因等等。所以这里:
Http Polling:基本上是AJAX,使用XmlHttpRequest。
Http Long Polling: AJAX但服务器保留响应,除非服务器有更新,服务器有更新后,它会发送它,然后客户端可以发送另一个请求。缺点是需要来回发送的额外标头数据会导致额外的开销。
Http Streaming:类似于长轮询,但服务器使用带有“Transfer Encoding:chunked”的标头进行响应,因此每次服务器发送一些数据时我们都不需要发起新请求(因此节省了额外的标头开销)。这里的缺点是我们必须“理解”并找出数据的结构,以区分服务器发送的多个块。
Java Applet,Flash,Silverlight:它们提供了通过tcp / ip连接到套接字服务器的能力,但由于它们是插件,开发人员不希望依赖它们。
WebSockets:他们是新的API,试图通过以下方式解决上述方法的缺点:
我还缺少其他重大差异吗?如果我重新询问或将SO上已有的许多问题合并到一个问题中,我很抱歉,但我只是想从SO和网络上关于这些概念的所有信息中完全理解。
谢谢!
答案 0 :(得分:82)
与您确定的差异有很多不同。
双面/定向:
为了增加延迟(近似值):
CORS(跨域支持):
本机二进制数据(类型化数组,blob):
带宽效率下降:
移动设备支持:
Javascript使用复杂度(从最简单到最复杂)。无可否认,复杂性措施有点主观。
另请注意,有一个名为Server-Sent Events的标准化HTTP流的W3C提案。它目前还处于早期发展阶段,旨在提供与WebSockets相似的标准Javascript API。
答案 1 :(得分:13)
其他一些很好的答案涵盖了很多方面。这里有点多了。
WebSockets相对于Java Applet,Flash或Silverlight等插件的唯一优势是WebSockets本身内置于浏览器中,不依赖于插件。
如果这意味着您可以使用Java Applet,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协议旨在成为更高级别协议的传输层。虽然您可以直接通过WebSocket连接发送JSON消息或什么不是,但它也可以携带标准或自定义协议。
例如,您可以通过WebSocket执行AMQP或XMPP,就像人们已经做过的那样。因此,客户端可以从AMQP代理接收消息,就像它直接连接到代理本身一样(在某些情况下它是)。
或者,如果您的现有服务器具有某些自定义协议,则可以通过WebSocket传输该服务器,从而将该后端服务器扩展到Web。通常,已锁定在企业中的现有应用程序可以使用WebSocket扩展其范围,而无需更改任何后端基础架构。
(当然,您希望能够安全地完成所有操作,因此请与供应商或WebSocket提供商联系。)
有些人将WebSocket称为Web的TCP。因为就像TCP传输更高级别的协议一样,WebSocket也是如此,但其方式与Web基础设施兼容。
因此,尽管通过WebSocket直接发送JSON(或其他)消息总是可行的,但也应考虑现有协议。因为对于你想要做的很多事情,可能已经考虑过这样做的协议。
对不起,如果我重新询问或将SO上已有的许多问题合并到一个问题中,但我只想完全理解SO上的所有信息。关于这些概念的网站。
这是一个很好的问题,答案都非常丰富!
答案 2 :(得分:10)
如果我可能会问另外一件事:我在某篇文章中看到过,http流式传输也可能由代理缓存,而websockets则不会。这是什么意思?
(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服务器。这样可以更快地响应最终用户,这总是很好,但这也意味着中心负载较少。这可以转化为降低硬件成本,降低网络成本等。所以这是一件好事。
在Web服务器上更新logo.gif时出现问题。代理将继续为旧图像提供服务而不知道有新图像。这会导致整个过期到期,因此代理只会在“过期”之前将图像缓存一小段时间,然后下一个请求通过代理到达Web服务器,然后刷新代理的缓存。还有更先进的解决方案,中央服务器可以推送到已知的缓存,等等,事情可以变得非常复杂。
这与您的问题有什么关系?
您询问了有关服务器将HTTP流式传输到客户端的HTTP流式传输。但是流式HTTP就像普通的HTTP一样,除了你不停止发送数据。如果Web服务器提供图像,它会将HTTP发送到最终结束的客户端:您已发送整个图像。如果你想发送数据,那就完全一样了,但是服务器只发送了很长时间(比如说这是一个庞大的巨大图像),甚至从未完成。
从代理的角度来看,它无法区分像图像这样的静态资源的HTTP或来自HTTP流的数据。在这两种情况下,客户端都发出了服务器的请求。代理记住了该请求以及响应。下次请求进入时,代理会提供相同的响应。
因此,如果您的客户提出股票价格请求,并获得响应,那么下一个客户可以提出相同的请求并获取缓存数据。可能不是你想要的!如果您要求股票价格,您需要最新数据,对吗?
所以这是一个问题。
有一些技巧和变通方法来处理这样的问题,这是事实。显然,你可以让HTTP流式传输工作,因为它现在正在使用。这对最终用户来说都是透明的,但是开发和维护这些架构的人必须跳过篮球并付出代价。它导致过于复杂的架构,这意味着更多的维护,更多的硬件,更复杂,更多的成本。这也意味着开发人员在关注应用程序,GUI和业务逻辑时,往往不得不关心他们不应该关注的事情 - 他们不应该关注底层的沟通。
答案 3 :(得分:4)
HTTP将客户端与服务器的连接数限制为2(尽管可以通过使用子域来缓解这种情况),并且已知IE已经急切地强制执行此操作。 Firefox和Chrome允许更多(虽然我不记得我的头脑究竟有多少)。这似乎不是一个大问题,但如果您经常使用1个连接进行实时更新,则所有其他请求都必须通过其他HTTP连接进行瓶颈。而且客户端拥有更多开放连接的问题会给服务器带来更多负担。
WebSockets是一种基于TCP的协议,因此不受此HTTP级别连接限制的影响(当然,浏览器支持不统一)。