133

I have read many posts on SO and the web regarding the keywords in my question title and learned a lot from them. 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. So here goes:

Http Polling: Basically AJAX, using 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. 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). 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.

WebSockets: they are the new API which tries to address the short comings of above methods in the following manner:

  • 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.
  • 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.
  • The only advantage of WebSockets over Long Polling is that of elimination of extra headers size & opening and closing of socket connection for request.

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.

Thanks!

Software Guy
  • 2,900
  • 4
  • 19
  • 20
  • 4
    [Server-Sent Events](http://www.w3.org/TR/eventsource/) may also worth looking at when you don't need bi-directional communication. – leggetter Sep 24 '12 at 10:42
  • 1
    This is a really useful question. I think it would potentially be more useful if there were one answer that multiple authors could contribute to. – leggetter Sep 24 '12 at 10:43
  • @leggetter Thanks Phil, thanks for the tip regarding server sent events. I am interested in learning about bi-directional communication scenarios. thanks. – Software Guy Sep 24 '12 at 11:06
  • 1
    With HTTP Streaming and Long-Polling you need a 2nd connection for bi-directional communication. One longer lived connection for the server -> client 'push' communication and a second short lived connection for the client -> server comms. This second connection is used to do things such as set up and change subscriptions to data. So, EventSource can be used in a bi-direction solution and in effect is actually a standardised solution born from HTTP Streaming and Long-Polling. – leggetter Sep 24 '12 at 21:55
  • 1
    You might also want to check out this classification of techniques I wrote: http://stackoverflow.com/questions/12078550/is-comet-obsolete-now-with-server-sent-events-and-websocket/12082152#12082152 – Alessandro Alinone Sep 26 '12 at 11:11
  • @leggetter Thanks a lot for the explaination Phil! – Software Guy Sep 26 '12 at 11:19
  • @AlessandroAlinone thanks! I'll check the link! – Software Guy Sep 26 '12 at 11:21
  • All of you rock guys :)) – securecurve Dec 28 '12 at 21:41
  • @leggetter, The server-sent events seems to be HTTP long polling as well, more over, it's the first time to hear about it, did you use it or heared about somebody else used it? – securecurve Dec 28 '12 at 21:50
  • @securecurve I *think* server-sent events are closer to [HTTP streaming](http://www.leggetter.co.uk/real-time-web-technologies-guide/realtime-web-technology-transport-mechanisms#http-streaming). I know that [SignalR](http://signalr.net) uses server-sent events. However, they are unidirectional so for more interactive functionality WebSockets are a better solution. – leggetter Jan 03 '13 at 10:54
  • Thanks dude, appreciated :)) – securecurve Jan 03 '13 at 14:38
  • Hello, I have a quesion about HTTP Streaming. I have servlet on some web server (in my case Weblogic but the behaviour is the same regardless of server isnt it?) for downloading files and I plan another for prividing currency rates that are changing 3 times per second (I cant use websockets) I wonder what would happen if 1000 users would download this file or connect to currency rates at the same time ? Each of them would create separate thread? –  Jul 23 '15 at 13:18

4 Answers4

98

There are more differences than the ones you have identified.

Duplex/directional:

  • Uni-directional: HTTP poll, long poll, streaming.
  • Bi-direcitonal: WebSockets, plugin networking

In order of increasing latency (approximate):

  • WebSockets
  • Plugin networking
  • HTTP streaming
  • HTTP long-poll
  • HTTP polling

CORS (cross-origin support):

  • WebSockets: yes
  • Plugin networking: Flash via policy request (not sure about others)
  • HTTP * (some recent support)

Native binary data (typed arrays, blobs):

  • WebSockets: yes
  • Plugin networking: not with Flash (requires URL encoding across ExternalInterface)
  • HTTP *: recent proposal to enable binary type support

Bandwidth in decreasing efficiency:

  • Plugin networking: Flash sockets are raw except for initial policy request
  • WebSockets: connection setup handshake and a few bytes per frame
  • HTTP streaming (re-use of server connection)
  • HTTP long-poll: connection for every message
  • HTTP poll: connection for every message + no data messages

Mobile device support:

  • WebSocket: iOS 4.2 and up. Some Android via Flash emulation or using Firefox for Android or Google Chrome for Android which both provide native WebSocket support.
  • Plugin networking: some Android. Not on iOS
  • HTTP *: mostly yes

Javascript usage complexity (from simplest to most complicated). Admittedly complexity measures are somewhat subjective.

  • WebSockets
  • HTTP poll
  • Plugin networking
  • HTTP long poll, streaming

Also note that there is a W3C proposal for standardizing HTTP streaming called Server-Sent Events. It is currently fairly early in it's evolution and is designed to provide a standard Javascript API with comparable simplicity to WebSockets.

leggetter
  • 14,640
  • 1
  • 50
  • 58
kanaka
  • 63,553
  • 21
  • 138
  • 135
  • 1
    Thanks a lot for the nice reply Kanaka. Can you please tell me why / how http streaming has a higher latency than websockets? maybe with a simple example? thanks a lot. – Software Guy Sep 23 '12 at 21:05
  • 2
    @SoftwareGuy. Many reasons. On recent browsers, you can use the XMLHTTPRequest onprogress event handler to be notified of data. But the spec says 50ms is the smallest notification interval. Otherwise you must poll for response data. Also, client sends establish a new HTTP connection and so significantly increase round-trip latency. Also, many web servers cut off HTTP connections after 30 seconds or so meaning you often have to keep re-establishing the server push connection. I've seen 5-10ms WebSocket roundtrip latencies on a local network. HTTP streaming latency would likely be 50ms+. – kanaka Sep 24 '12 at 01:16
  • Thanks a lot for the detailed reply :) – Software Guy Sep 24 '12 at 09:29
  • I don't believe HTTP streaming does have a higher latency than WebSockets once the connection has been established. In most browsers as soon as a new piece of data is received the `xhr.onreadystatechange` event will fire and the new data will be accessible via the `xhr.responseText`. The main problems with HTTP streaming are the inconsistencies of how you use them cross browser (multi-part replace, responseText keeps on growing, initial buffer flush etc). Obviously, the main latency problem is introduced when you want bi-directional communication and it's the 2nd connection that's the problem. – leggetter Sep 24 '12 at 10:52
  • 1
    @leggetter Thanks Phil, you mean sending data from the client to the server via http streaming will cause overhead? is sending data to the server even possible over http streaming without opening a new connection? Thanks. – Software Guy Sep 24 '12 at 11:03
  • @leggetter, round-trip latency will be slower with HTTP streaming just because of the client connection latency (so even if server->client latency is similar, overall it's still slower). Can you cite evidence that onreadystatechange is widely supported and actually has low latency? It also seems that this is not intended by the spec (http://dvcs.w3.org/hg/xhr/raw-file/tip/Overview.html) and so can't be counted on to exist in the future or be consistent across browsers even if true today. It seems that IE and even webkit may have limited support: https://bugs.webkit.org/show_bug.cgi?id=14392 – kanaka Sep 24 '12 at 14:54
  • @kanaka round-trip latency/bi-directional communcation, yes. For just push from server -> client, probably not (handshake v headers). Once the HTTP Streaming connection is established there aren't the HTTP headers to introduce increased latency. And the evented nature of 'onreadystatechange' means that as soon as data is available it can be processed. `onreadystatechange` fires when new data is available. If mult-part replace is used then the `responseText` contains just the new data. If not (IE and your link) then the `responseText` grows in size needs to be parsed to get just the new data. – leggetter Sep 24 '12 at 22:09
  • Hi, I have a quesion about HTTP Streaming. I have servlet on some web server (in my case Weblogic but the behaviour is the same regardless of server isnt it?) for downloading files and I plan another for prividing currency rates that are changing 3 times per second (I cant use websockets) I wonder what would happen if 1000 users would download this file or connect to currency rates at the same time ? Each of them would create separate thread? –  Jul 23 '15 at 13:18
  • It would be nice to also point out the energy usage implications of each approach. It probably needs testing, but practical experience has taught me that polling tends to eat battery much faster than web socket. Not sure if that's the idiosyncrasies of my experience or a good data point. – Nathan May 03 '16 at 21:05
  • 1
    @Nathan sounds like a good masters degree thesis project! Certainly, polling will keep the system busier than an event driven model, but what exactly the power savings might be would need fairly extensive empirical testing at different scales. – kanaka May 04 '16 at 13:54
13

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.

If by this you mean that you can use Java Applets, Flash, or Silverlight to establish a socket connection, then yes, that is possible. 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.

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.

Those socket alternatives (Java, Flash, and Silverlight) are difficult to use securely in a cross-origin architecture. 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. Flash and Java have had this capability for probably at least 10 years, and yet it's not prevalent.

The WebSocket standard was able to start with a fresh approach, bearing those restrictions in mind, and hopefully having learned some lessons from them.

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).

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. 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.

For example, if you rely on WebSocket for a cross-origin connection, that will work fine. 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. 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.

It's not as simple as opening up an HTTP stream and sitting back as your data flows for minutes, hours, or longer. 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. That's not too real-time.

While HTTP streaming can be a viable alternative when WebSocket is not available, it is not a panacea. It needs a good understanding to work in a robust way out in the badlands of the Web in real-world conditions.

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. While you can send JSON messages or what-not directly over a WebSocket connection, it can also carry standard or custom protocols.

For example, you could do AMQP or XMPP over WebSocket, as people have already done. 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).

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. 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.

(Naturally, you'd want to be able to do all that securely so check with the vendor or WebSocket provider.)

Some people have referred to WebSocket as TCP for the Web. Because just like TCP transports higher-level protocols, so does WebSocket, but in a way that's compatible with Web infrastructure.

So while sending JSON (or whatever) messages directly over WebSocket is always possible, one should also consider existing protocols. 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.

This was a great question, and the answers have all been very informative!

Robin Zimmermann
  • 2,468
  • 1
  • 15
  • 15
  • Thanks a lot Robin for the excellent help and info. 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. what does that mean? – Software Guy Sep 24 '12 at 09:28
  • Because StackOverflow limits the size in response comments, I've given my answer below: http://stackoverflow.com/questions/12555043/my-understanding-of-http-polling-long-polling-http-streaming-and-websockets/12569110#12569110 – Robin Zimmermann Sep 24 '12 at 16:27
  • @RobinZimmermann, your answer is my favorite. +1 for the really good detailed answer. – securecurve Dec 28 '12 at 22:09
10

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. what does that mean?

(StackOverflow limits the size of comment responses, so I've had to answer here rather than inline.)

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. The server responds with HTTP that contains the HTML for the page. Then the browser sees that there are resources in the page, so it starts requesting the CSS files, JavaScript files, and images of course. 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. 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. That request goes through the proxy all the way to the central web server, which serves up 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.

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. 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. 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. 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. But streaming HTTP is just like regular HTTP except you don't stop sending data. If a web server serves an image, it sends HTTP to the client that eventually ends: you've sent the whole image. 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. 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. 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.

Robin Zimmermann
  • 2,468
  • 1
  • 15
  • 15
  • 1
    excellent detail Robin, thanks so much! i really appreciate your thorough response. i've learned so much from all the great people here already! :) – Software Guy Sep 24 '12 at 18:37
4

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. Firefox and Chrome allow more (although I can't remember of the top of my head exactly how many). 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. 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).

TheJuice
  • 4,334
  • 2
  • 24
  • 35
  • thanks thejuice, so besides the issue of multiple simultaneous connections as highlighted by you, are the rest of my assumptions regarding websockets correct? – Software Guy Sep 23 '12 at 19:47