简体   繁体   English

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

[英]My Understanding of HTTP Polling, Long Polling, HTTP Streaming and WebSockets

I have read many posts on SO and the web regarding the keywords in my question title and learned a lot from them. 我在SO和网上看了很多关于我的问题标题中的关键词的帖子,并从中学到了很多。 Some of the questions I read are related to specific implementation challenges while others focus on general concepts. 我读到的一些问题与具体的实施挑战有关,而其他问题则侧重于一般概念。 I just want to make sure I understood all of the concepts and the reasoning why technology X was invented over technology Y and so on. 我只是想确保我理解为什么技术X是在技术Y上发明的所有概念和原因等等。 So here goes: 所以这里:

Http Polling: Basically AJAX, using XmlHttpRequest. Http Polling:基本上是AJAX,使用XmlHttpRequest。

Http Long Polling: AJAX but the server holds on to the response unless the server has an update, as soon as the server has an update, it sends it and then the client can send another request. Http Long Polling: AJAX但服务器保持响应,除非服务器有更新,一旦服务器有更新,它发送它然后客户端可以发送另一个请求。 Disadvantage is the additional header data that needs to be sent back and forth causing additional overhead. 缺点是需要来回发送额外的头数据会导致额外的开销。

Http Streaming: Similar to long polling but the server responds with a header with "Transfer Encoding: chunked" and hence we do not need to initiate a new request every time the server sends some data (and hence save the additional header overhead). Http Streaming:类似于长轮询,但是服务器使用带有“Transfer Encoding:chunked”的标头进行响应,因此每次服务器发送一些数据时我们都不需要发起新的请求(因此节省了额外的头部开销)。 The drawback here is that we have to "understand" and figure out the structure of the data to distinguish between multiple chunks sent by the server. 这里的缺点是我们必须“理解”并找出数据的结构,以区分服务器发送的多个块。

Java Applet, Flash, Silverlight: They provide the ability to connect to socket servers over tcp/ip but since they are plugins, developers don't want to depend on them. Java Applet,Flash,Silverlight:它们提供了通过tcp / ip连接到套接字服务器的能力,但由于它们是插件,开发人员不希望依赖它们。

WebSockets: they are the new API which tries to address the short comings of above methods in the following manner: WebSockets:它们是新的API,它试图通过以下方式解决上述方法的缺点:

  • The only advantage of WebSockets over plugins like Java Applets, Flash or Silverlight is that WebSockets are natively built into browsers and does not rely on plugins. 与Java Applet,Flash或Silverlight等插件相比,WebSockets的唯一优势是WebSockets本身内置于浏览器中,不依赖于插件。
  • The only advantage of WebSockets over http streaming is that you don't have to make an effort to "understand" and parse the data received. WebSockets优于http流的唯一优势是您不必努力“理解”并解析收到的数据。
  • The only advantage of WebSockets over Long Polling is that of elimination of extra headers size & opening and closing of socket connection for request. WebSockets优于长轮询的唯一优势是消除额外的标头大小以及为请求打开和关闭套接字连接。

Are there any other significant differences that I am missing? 我还缺少其他重大差异吗? I'm sorry if I am re-asking or combining many of the questions already on SO into a single question, but I just want to make perfect sense out of all the info that is out there on SO and the web regarding these concepts. 如果我重新询问或将SO上已有的许多问题合并到一个问题中,我很抱歉,但我只是想从SO和网络上关于这些概念的所有信息中完全理解。

Thanks! 谢谢!

There are more differences than the ones you have identified. 与您确定的差异相比,存在更多差异。

Duplex/directional: 双面打印/方向:

  • Uni-directional: HTTP poll, long poll, streaming. 单向:HTTP轮询,长轮询,流式传输。
  • Bi-direcitonal: WebSockets, plugin networking Bi-direcitonal:WebSockets,插件网络

In order of increasing latency (approximate): 为了增加延迟(近似值):

  • WebSockets 的WebSockets
  • Plugin networking 插件网络
  • HTTP streaming HTTP流媒体
  • HTTP long-poll HTTP长轮询
  • HTTP polling HTTP轮询

CORS (cross-origin support): CORS(跨域支持):

  • WebSockets: yes WebSockets:是的
  • Plugin networking: Flash via policy request (not sure about others) 插件网络:通过策略请求Flash(不确定其他人)
  • HTTP * (some recent support) HTTP *(最近的一些支持)

Native binary data (typed arrays, blobs): 本机二进制数据(类型化数组,blob):

  • WebSockets: yes WebSockets:是的
  • Plugin networking: not with Flash (requires URL encoding across ExternalInterface) 插件网络:不使用Flash(需要跨ExternalInterface进行URL编码)
  • HTTP *: recent proposal to enable binary type support HTTP *:最近提出启用二进制类型支持的提议

Bandwidth in decreasing efficiency: 带宽效率下降:

  • Plugin networking: Flash sockets are raw except for initial policy request 插件网络:除初始策略请求外,Flash套接字是原始的
  • WebSockets: connection setup handshake and a few bytes per frame WebSockets:连接设置握手和每帧几个字节
  • HTTP streaming (re-use of server connection) HTTP流(重新使用服务器连接)
  • HTTP long-poll: connection for every message HTTP long-poll:每条消息的连接
  • HTTP poll: connection for every message + no data messages HTTP轮询:每条消息的连接+没有数据消息

Mobile device support: 移动设备支持:

  • WebSocket: iOS 4.2 and up. WebSocket:iOS 4.2及更高版本。 Some Android via Flash emulation or using Firefox for Android or Google Chrome for Android which both provide native WebSocket support. 一些Android通过Flash模拟或使用Android for AndroidGoogle Chrome for Android ,它们都提供原生WebSocket支持。
  • Plugin networking: some Android. 插件网络:一些Android。 Not on iOS 不在iOS上
  • HTTP *: mostly yes HTTP *:大多是的

Javascript usage complexity (from simplest to most complicated). Javascript使用复杂度(从最简单到最复杂)。 Admittedly complexity measures are somewhat subjective. 无可否认,复杂性措施有点主观。

  • WebSockets 的WebSockets
  • HTTP poll HTTP轮询
  • Plugin networking 插件网络
  • HTTP long poll, streaming HTTP长轮询,流式传输

Also note that there is a W3C proposal for standardizing HTTP streaming called Server-Sent Events . 另请注意,有一个W3C提议用于标准化称为服务器发送事件的 HTTP流。 It is currently fairly early in it's evolution and is designed to provide a standard Javascript API with comparable simplicity to WebSockets. 它目前还处于早期发展阶段,旨在提供标准的Javascript API,其简单性与WebSockets相当。

Some great answers from others that cover a lot of ground. 来自其他人的一些很好的答案涵盖了很多方面。 Here's a little bit extra. 这里有点多余。

The only advantage of WebSockets over plugins like Java Applets, Flash or Silverlight is that WebSockets are natively built into browsers and does not rely on plugins. 与Java Applet,Flash或Silverlight等插件相比,WebSockets的唯一优势是WebSockets本身内置于浏览器中,不依赖于插件。

If by this you mean that you can use Java Applets, Flash, or Silverlight to establish a socket connection, then yes, that is possible. 如果这意味着您可以使用Java Applet,Flash或Silverlight来建立套接字连接,那么是的,这是可能的。 However you don't see that deployed in the real world too often because of the restrictions. 但是,由于这些限制,您不会经常在现实世界中部署。

For example, intermediaries can and do shutdown that traffic. 例如,中介可以并且确实关闭该流量。 The WebSocket standard was designed to be compatible with existing HTTP infrastructure and so is far less prone to being interfered with by intermediaries like firewalls and proxies. WebSocket标准旨在与现有的HTTP基础架构兼容,因此不太容易受到防火墙和代理等中介的干扰。

Moreover, WebSocket can use port 80 and 443 without requiring dedicated ports, again thanks to the protocol design to be as compatible as possible with existing HTTP infrastructure. 此外,WebSocket可以使用端口80和443而无需专用端口,这要归功于协议设计与现有HTTP基础架构尽可能兼容。

Those socket alternatives (Java, Flash, and Silverlight) are difficult to use securely in a cross-origin architecture. 那些套接字替代品(Java,Flash和Silverlight)很难在跨源体系结构中安全使用。 Thus people often attempting to use them cross-origin will tolerate the insecurities rather than go to the effort of doing it securely. 因此,经常试图使用它们来源的人会容忍不安全感,而不是努力安全地做到这一点。

They can also require additional "non-standard" ports to be opened (something administrators are loathe to do) or policy files that need to be managed. 他们还可能需要打开额外的“非标准”端口(管理员不愿意这样做)或需要管理的策略文件。

In short, using Java, Flash, or Silverlight for socket connectivity is problematic enough that you don't see it deployed in serious architectures too often. 简而言之,使用Java,Flash或Silverlight进行套接字连接是有问题的,您不会经常在严肃的架构中看到它。 Flash and Java have had this capability for probably at least 10 years, and yet it's not prevalent. Flash和Java已经拥有这种能力至少10年,但它并不普遍。

The WebSocket standard was able to start with a fresh approach, bearing those restrictions in mind, and hopefully having learned some lessons from them. WebSocket标准能够以一种全新的方法开始,并考虑到这些限制,并希望从中吸取教训。

Some WebSocket implementations use Flash (or possibly Silverlight and/or Java) as their fallback when WebSocket connectivity cannot be established (such as when running in an old browser or when an intermediary interferes). 当无法建立WebSocket连接时(例如在旧浏览器中运行或中间人干扰时),某些WebSocket实现使用Flash(或可能是Silverlight和/或Java)作为其后备。

While some kind of fallback strategy for those situations is smart, even necessary, most of those that use Flash et al will suffer from the drawbacks described above. 虽然针对这些情况的某种回退策略是明智的,甚至是必要的,但大多数使用Flash等的人都会遇到上述缺点。 It doesn't have to be that way -- there are workarounds to achieve secure cross-origin capable connections using Flash, Silverlight, etc -- but most implementations won't do that because it's not easy. 它不一定是这样 - 有使用Flash,Silverlight等实现安全的跨源连接的解决方法 - 但是大多数实现都不会这样做,因为它并不容易。

For example, if you rely on WebSocket for a cross-origin connection, that will work fine. 例如,如果您依赖WebSocket进行跨源连接,则可以正常工作。 But if you then run in an old browser or a firewall/proxy interfered and rely on Flash, say, as your fallback, you will find it difficult to do that same cross-origin connection. 但是,如果您在旧的浏览器或受干扰的防火墙/代理中运行并依赖Flash,比如说,作为您的后备,您将发现难以进行相同的跨源连接。 Unless you don't care about security, of course. 当然,除非你不关心安全性。

That means it's difficult have a single unified architecture that works for native and non-native connections, unless you're prepared to put in quite a bit of work or go with a framework that has done it well. 这意味着很难有一个统一的架构适用于本机和非本机连接,除非你准备投入相当多的工作或者使用已经做得很好的框架。 In an ideal architecture, you wouldn't notice if the connections were native or not; 在理想的架构中,您不会注意到连接是否是本机的; your security settings would work in both cases; 您的安全设置在两种情况下都有效; your clustering settings would still work; 您的群集设置仍然有效; your capacity planning would still hold; 你的容量规划仍然存在; and so on. 等等。

The only advantage of WebSockets over http streaming is that you don't have to make an effort to "understand" and parse the data received. WebSockets优于http流的唯一优势是您不必努力“理解”并解析收到的数据。

It's not as simple as opening up an HTTP stream and sitting back as your data flows for minutes, hours, or longer. 它并不像打开HTTP流那样简单,只需数据流动数分钟,数小时或更长时间即可。 Different clients behave differently and you have to manage that. 不同的客户端行为不同,您必须管理它。 For example some clients will buffer up the data and not release it to the application until some threshold is met. 例如,某些客户端将缓冲数据,并且在满足某个阈值之前不会将其释放到应用程序。 Even worse, some won't pass the data to the application until the connection is closed. 更糟糕的是,在连接关闭之前,有些人不会将数据传递给应用程序。

So if you're sending multiple messages down to the client, it's possible that the client application won't receive the data until 50 messages worth of data has been received, for example. 因此,如果您向客户端发送多条消息,则客户端应用程序可能无法接收数据,直到收到50条消息的数据为止。 That's not too real-time. 那不是太实时。

While HTTP streaming can be a viable alternative when WebSocket is not available, it is not a panacea. 虽然当WebSocket不可用时,HTTP流是一种可行的替代方案,但它并不是万能药。 It needs a good understanding to work in a robust way out in the badlands of the Web in real-world conditions. 在现实世界的条件下,需要很好地理解在Web的荒地中以健壮的方式工作。

Are there any other significant differences that I am missing? 我还缺少其他重大差异吗?

There is one other thing that noone has mentioned yet, so I'll bring it up. 还有一件事没有提到,所以我会提出来的。

The WebSocket protocol was designed to a be a transport layer for higher-level protocols. WebSocket协议旨在成为更高级别协议的传输层。 While you can send JSON messages or what-not directly over a WebSocket connection, it can also carry standard or custom protocols. 虽然您可以直接通过WebSocket连接发送JSON消息或什么不是,但它也可以携带标准或自定义协议。

For example, you could do AMQP or XMPP over WebSocket, as people have already done. 例如,您可以通过WebSocket执行AMQP或XMPP,就像人们已经做过的那样。 So a client could receive messages from an AMQP broker as if it were connected directly to the broker itself (and in some cases it is). 因此,客户端可以从AMQP代理接收消息,就好像它直接连接到代理本身(在某些情况下它是)。

Or if you have an existing server with some custom protocol, you can transport that over WebSocket, thus extending that back-end server to the Web. 或者,如果您的现有服务器具有某些自定义协议,则可以通过WebSocket传输该服务器,从而将该后端服务器扩展到Web。 Often an existing application that has been locked in the enterprise can broaden it's reach using WebSocket, without having to change any of the back-end infrastructure. 通常,已锁定在企业中的现有应用程序可以使用WebSocket扩展其范围,而无需更改任何后端基础结构。

(Naturally, you'd want to be able to do all that securely so check with the vendor or WebSocket provider.) (当然,您希望能够安全地执行所有操作,因此请与供应商或WebSocket提供商联系。)

Some people have referred to WebSocket as TCP for the Web. 有些人将WebSocket称为Web的TCP。 Because just like TCP transports higher-level protocols, so does WebSocket, but in a way that's compatible with Web infrastructure. 因为就像TCP传输更高级别的协议一样,WebSocket也是如此,但它与Web基础架构兼容。

So while sending JSON (or whatever) messages directly over WebSocket is always possible, one should also consider existing protocols. 因此,尽管通过WebSocket直接发送JSON(或其他)消息总是可行的,但也应考虑现有协议。 Because for many things you want to do, there's probably a protocol that's already been thought of to do it. 因为对于你想要做的很多事情,可能已经考虑过这样做的协议。

I'm sorry if I am re-asking or combining many of the questions already on SO into a single question, but I just want to make perfect sense out of all the info that is out there on SO and the web regarding these concepts. 如果我重新询问或将SO上已有的许多问题合并到一个问题中,我很抱歉,但我只是想从SO和网络上关于这些概念的所有信息中完全理解。

This was a great question, and the answers have all been very informative! 这是一个很好的问题,答案都非常丰富!

If I may ask one additional thing: I came across in an article somewhere that says that http streaming may also be cached by proxies while websockets are not. 如果我可能会问另外一件事:我在某篇文章中遇到过这样的文章:http流也可能被代理缓存,而websockets则不会。 what does that mean? 那是什么意思?

(StackOverflow limits the size of comment responses, so I've had to answer here rather than inline.) (StackOverflow限制了评论响应的大小,所以我必须在这里回答而不是内联。)

That's a good point. 那是个很好的观点。 To understand this, think about a traditional HTTP scenario... Imagine a browser opened a web page, so it requests http://example.com , say. 要理解这一点,请考虑一下传统的HTTP场景......想象一下,浏览器打开了一个网页,所以它请求http://example.com The server responds with HTTP that contains the HTML for the page. 服务器使用包含页面HTML的HTTP进行响应。 Then the browser sees that there are resources in the page, so it starts requesting the CSS files, JavaScript files, and images of course. 然后浏览器看到页面中有资源,因此它开始请求CSS文件,JavaScript文件和图像。 They are all static files that will be the same for all clients requesting them. 它们都是静态文件,对于请求它们的所有客户端都是相同的。

Some proxies will cache static resources so that subsequent requests from other clients can get those static resources from the proxy, rather than having to go all the way back to the central web server to get them. 一些代理将缓存静态资源,以便来自其他客户端的后续请求可以从代理获取这些静态资源,而不必一直返回到中央Web服务器来获取它们。 This is caching, and it's a great strategy to offload requests and processing from your central services. 这是缓存,从中央服务卸载请求和处理是一个很好的策略。

So client #1 requests http://example.com/images/logo.gif , say. 因此,客户#1请求http://example.com/images/logo.gif That request goes through the proxy all the way to the central web server, which serves up logo.gif. 该请求一直通过代理到中央Web服务器,后者提供了logo.gif。 As logo.gif passes through the proxy, the proxy will save that image and associate it with the address http://example.com/images/logo.gif . 当logo.gif通过代理时,代理将保存该图像并将其与地址http://example.com/images/logo.gif相关联。

When client #2 comes along and also requests http://example.com/images/logo.gif , the proxy can return the image and no communication is required back to the web server in the center. 当客户端#2出现并请求http://example.com/images/logo.gif时 ,代理可以返回图像,并且不需要回复到中心的Web服务器。 This gives a faster response to the end user, which is always great, but it also means that there is less load on the center. 这样可以更快地响应最终用户,这总是很好,但这也意味着中心负载较少。 That can translate to reduced hardware costs, reduced networking costs, etc. So it's a good thing. 这可以转化为降低硬件成本,降低网络成本等。所以这是一件好事。

The problem arises when the logo.gif is updated on the web server. 在Web服务器上更新logo.gif时会出现问题。 The proxy will continue to serve the old image unaware that there is a new image. 代理将继续为旧图像提供服务而不知道有新图像。 This leads to a whole thing around expiry so that the proxy will only cache the image for a short time before it "expires" and the next request goes through the proxy to the web server, which then refreshes the proxy's cache. 这会导致整个过期到期,因此代理只会在“过期”之前将图像缓存一小段时间,然后下一个请求通过代理到达Web服务器,然后刷新代理的缓存。 There are also more advanced solutions where a central server can push out to known caches, and so on, and things can get pretty sophisticated. 还有更先进的解决方案,中央服务器可以推送到已知的缓存,等等,事情可以变得非常复杂。

How does this tie in to your question? 这与你的问题有什么关系?

You asked about HTTP streaming where the server is streaming HTTP to a client. 您询问了有关服务器将HTTP流式传输到客户端的HTTP流式传输。 But streaming HTTP is just like regular HTTP except you don't stop sending data. 但是流式HTTP就像普通的HTTP一样,除了你不停止发送数据。 If a web server serves an image, it sends HTTP to the client that eventually ends: you've sent the whole image. 如果Web服务器提供图像,它会将HTTP发送到最终结束的客户端:您已发送整个图像。 And if you want to send data, it's exactly the same, but the server just sends for a really long time (like it's a massively gigantic image, say) or even never finishes. 如果你想发送数据,它是完全一样的,但是服务器只是发送了很长时间(比如它是一个巨大的巨大图像),甚至从未完成。

From the proxy's point of view, it cannot distinguish between HTTP for a static resource like an image, or data from HTTP streaming. 从代理的角度来看,它无法区分HTTP作为静态资源(如图像)或数据来自HTTP流。 In both of those cases, the client made a request of the server. 在这两种情况下,客户端都发出了服务器的请求。 The proxy remembered that request and also the response. 代理记住了该请求以及响应。 The next time that request comes in, the proxy serves up the same response. 下次请求进入时,代理会提供相同的响应。

So if your client made a request for stock prices, say, and got a response, then the next client may make the same request and get the cached data. 因此,如果您的客户提出股票价格请求,并获得响应,则下一个客户端可以发出相同的请求并获取缓存数据。 Probably not what you want! 可能不是你想要的! If you request stock prices you want the latest data, right? 如果您要求股票价格,您需要最新数据,对吧?

So it's a problem. 所以这是一个问题。

There are tricks and workarounds to handle problems like that, it is true. 有一些技巧和变通方法来处理这样的问题,这是事实。 Obviously you can get HTTP streaming to work since it's it's in use today. 显然,你可以让HTTP流式传输工作,因为它现在正在使用。 It's all transparent to the end user, but the people who develop and maintain those architectures have to jump through hoops and pay a price. 这对最终用户来说都是透明的,但是开发和维护这些架构的人必须跳过篮球并付出代价。 It results in over-complicated architectures, which means more maintenance, more hardware, more complexity, more cost. 它导致过于复杂的架构,这意味着更多的维护,更多的硬件,更复杂,更多的成本。 It also means developers often have to care about something they shouldn't have to when they should just be focussing on the application, GUI, and business logic -- they shouldn't have to be concerned about the underlying communication. 这也意味着开发人员在关注应用程序,GUI和业务逻辑时,往往不得不关心他们不应该关注的事情 - 他们不应该关注底层的沟通。

HTTP limits the number of connections a client can have with a server to 2 (although this can be mitigated by using subdomains) and IE has been known to enforce this eagerly. HTTP将客户端与服务器的连接数限制为2(尽管可以通过使用子域来缓解这种情况),并且已知IE已经急切地强制执行此操作。 Firefox and Chrome allow more (although I can't remember of the top of my head exactly how many). Firefox和Chrome允许更多(虽然我不记得我的头脑究竟有多少)。 This might not seem like a huge issue but if you are using 1 connection constantly for real-time updates, all other requests have to bottleneck through the other HTTP connection. 这似乎不是一个大问题,但如果您经常使用1个连接进行实时更新,则所有其他请求都必须通过其他HTTP连接进行瓶颈。 And there is the matter of having more open connections from clients puts more load on the server. 而且客户端有更多开放连接的问题会给服务器带来更多负担。

WebSockets are a TCP-based protocol and as such don't suffer from this HTTP-level connection limit (but, of course, browser support is not uniform). WebSockets是基于TCP的协议,因此不受此HTTP级别连接限制(但当然,浏览器支持不统一)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM