I am implementing a system where I need real-time updates. I have been looking at certain scenarios and among all was Comet. Implementing this I do not see any way this is different from traditional long-polling.
In both cases you have to send a request, and then the server send a response back. In the browser you interpret the response and then you start a new request.
So why should I use comet if in both cases I need to open and close connections.
Some Comet techniques don't require that you constantly open new requests (the chunked hidden iframe, for instance), the idea being to hold the request open and have the server periodically sending data. But this doesn't work well across all major browsers without (as one Wikipedia contributor delicately put it) negative side-effects, hence the long-polling technique. More in the linked article.
As mentioned by Marcelo, Comet is usually used to describe any techniques for "HTTP streaming", including long-polling. In some cases, Comet might also refer more specifically to the Bayeux Protocol. For instance, the jQuery Comet plugin is of this protocol. From the Bayeux website:
Delivery of asynchronous messages from the server to a web client is often described as server-push.
The combination of server push techniques with an Ajax web application has been called Comet.
CometD is a project by the Dojo Foundation to provide multiple implementation of the Bayeux protocol in several programming languages.
Bayeux is an attempt to standardize a publish/subscribe protocol using Comet techniques, allowing for vendors of client and server side libraries to create interoperable components.
Comet is an umbrella term for a wide range of asynchronous update techniques, of which long-polling is just one.
If you want to push insteal of pulling, you can use JPE.
Related
I'm setting up a stock-ticker like web-page, written in JavaScript. I am also writing the server that the page talks to, in C++.
I would like to make the web page efficient, such that it makes sends single subscription message to the app server, and then holds a keep-alive connection open, constantly receiving inbound data pushed from the app server.
At the moment, I have to re-issue the web clients' subscription call every time I receive data from the server. The problem is that each time the XHR object hits readyState(4), the call is effectively completed. Any data arriving at the web page after this is ignored. The web-client can resend data and that resets the object, but the send is unnecessary, and is only being used to reset the XHR object.
I would like to know if it is possible to somehow reset the existing XHR object, and put it into a state where it expects more inbound data, so that when more data is pushed to the web page, the web page responds and processes it.
Thanks in advance for any help you can give. Note: Not using JQuery on this project.
I highly recommend looking into Websockets, especially a library like socket.io, which encapsulates various browser's implementations of Websocket transports into a single API (WS, JSON, JSONP, Flash and Long Polling).
Socket.io client libraries should be now be supported by all major browsers. Your only challenge might be locating a C++ specific server implementation. Hopefully this SO question might be of some help
Otherwise, your only other option is long-polling or comet on the client with a suitable server-side implementation that would scale (i.e. something like an event driven server like NginX as opposed to a thread-per-connection architecture.)
I do appreciate that you are committed to C++ but my humble advise would be to investigate Node.js as it can and does provide a very performant solution with very little effort.
HTH and all the best.
HTTP is a one-off protocol: one request, one response, and you're done. If you want to keep a connection open, you can use Websockets (MDN reference page, client-side code example). However consider it won't be supported on older browsers (IE, for example, just started supporting Websockets on version 10), so you'll probably need to implement a fallback using XHR and long-polling.
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!
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.
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!
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.
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).
I have to program websites, but I rather don't like the static HTML nature. I prefer more of a client-server architecture.
Now I've figured, that with XMLhttp, you can basically dynamically update your page and send/request for information/action to/from a server. So this would basically cover the client area.
But to complete a client-server architecture, it is necessary for the server to send/request information, too, without being queried.
Is there any way, for example for a chat server, to send back a received message to all clients (the clients use a web browser) without that the clients have to query in a fixed interval? I want to implement that one can see while you type something in.
There are several different ways to accomplish this. Some of them are already answered here, but I wanted to include a few more as well as my thoughts on them.
1. Polling
Frequent requests are made to the server to check for new info. This is the worst way to do this, but probably the easiest. If your site will have a low number of users, it might be worth doing it this way.
This can be accomplished by using setInterval(myFunction, n) in javascript to send XMLHttpRequests to the server every n milliseconds. Then, on the server, you respond to this with your new info, when you have it, or some message that implies no new info.
2. Long Polling
When the page is loaded, it makes a request to the server for new info. The server holds the connection open until there is something to send back. This method reduces the amount of network traffic used, but increases the resources used on the server. You can use this for a small number of users, but it doesn't scale very well.
The easiest way to do this is to have the page that handles the AJAX request simply wait for new information to be available, then respond. This can tie up a lot connections on your server. So, use with care.
3. COMET
COMET is basically long polling, but the server is setup properly for it. It knows that these connections aren't "real" and it uses less resources to handle them. This is a great solution for this problem, but it requires that the server is explicitly setup for this purpose. There are COMET servers and COMET addins for other popular servers, but it will require some setup and sometimes some money.
Implementing this on .NET isn't the easiest thing in the world. You can pay for solutions, try to find someone else's code that does something similar, or try to write it yourself. I've not found any decent free solutions for this. If someone else has, please comment.
4. RIA
Another solution would be to include Flash, Silverlight, or Java Applet on your page. People often do this by using a 1x1 object so that they can use Flash or Silverlight to talk to the server. If you don't mind adding the dependency, this is a decent solution. If you already know Silverlight or Flash, it could be relatively simple to implement.
You can find tutorials on the internet for each of these options.
5. Web Sockets
If you are on the cutting edge, you can look into Web Sockets. It's only available in the latest builds of modern browsers. It was part of HTML5, but it might be its own spec now. Regardless, it means that older browsers won't be able to handle it. But, if you don't mind limiting yourself to the latest of browsers, you can use this amazing feature.
I believe that Chromium is the only browser that currently supports it. However, there is work being done to implement this in Firefox and WebKit.
I'll spare you the controversy and simply say that this does exactly what you want it to. The Abstract of the spec says it all.
This specification defines an API that enables Web pages to use the Web Sockets protocol for two-way communication with a remote host.
Special Mention
If you are interested in the world of Node JS, you can't go wrong with Socket IO. It will implement the best of whichever technology is available to the browser.
Conclusion
The best option is Socket.IO on Node JS. However, for an ASP.Net solution, go for COMET or Web Sockets, if you can. Otherwise, using Flash/Silverlight isn't terrible. Finally, polling and long polling should be last resorts. You could always support one of these, then fall back to another if there isn't support for it in the client's browser.
Yes, you can use COMET.
The client has to tell the server when the client-user begins typing. You've got a couple options here.
Frequent requests from the server for the latest activity. This would be taking place for each user involved in the chat. The same request could be used to send user-specific activity to the server as well: "Jonathan is typing..."
Long-polling. This essentially requests information from the server, and the server keeps the connection opened until it has something to send back. So your requests are minimized, but your connections stay opened longer.
Depending on your traffic, type of data being transmitted, server-environment, and many other factors, one of these options may shine more than the other.
You can use Silverlight for push notifications. Look at PollingDuplexHttpBinding. Since you are using ASP.Net MVC, adding Silverlight will be easy.
Look at this page for more information.
Based upon the REST architecture the html system is based upon, the servers role is to simply act as a resource for the client to pull from. I am generalizing but there are tools to implement this type of action on the client side, rather than on the server side.
You are better off writing/using a library that can request updates from the server periodically. You can encapsulate these types of requests in a javascript object that can fire events. This way your client side script can act like it's getting notified from the server. Review some common stuff with COMET you can probably find some tools to help you client side code.
HTML 5 has some tentative attempts at this type of functionality, but if you want your app to work on older browsers, your better off using more stable methods, like AJAX requested updates.
I just learned about the AJAX Push Engine but it runs on Linux/Apache which is not an option for me.
http://www.ape-project.org/
Currently with AJAX to keep a page current I have to poll the server frequently which is not great for a high traffic site. The option to push data to the client only when necessary is a great option, but natively JavaScript does not support sockets, AFAIK. One trick I read about, but the site is now gone, is to use a Flash module to handle socket communications and relay message to JavaScript.
The trouble with researching this approach is that "JavaScript push" as keywords come up with the push function for arrays instead of the context I want.
How could establish a persistent connection with the server to do push communications in the browser? Do I need Flash/ActionScript or is there another option that would work with all of the currently active browsers? (IE6/7/8, FF3, Safari, Chrome)
When it comes to the server I also need to work out the complications due to Origin policy as well as port security. I appreciate anything you can point out that will explain the available options.
What you want is COMET, or I would also look up long polling.
I asked a similar question.
The Direct Web Remoting (DWR) library supports Reverse Ajax, which sounds like what you are looking for. It supports Comet (along with Polling and PiggyBack). More info on their website: http://directwebremoting.org/dwr/index.html
This is interesting stuff, but I did not read anything about scalability issues on these Wiki pages. What does a web server do if you have 10,000 open long-polling connections?
Also, for those not familiar with the underlying concepts, it is important to understand that pushing data from the server to the client in an ad-hoc fashion is impossible and will always be. Even if the HTTP protocol supported this, the network would not, particularly if there is a NAT firewall involved.
So any solutions that claim to offer server push communication must rely on connections that are initiated by the client, kept open, and will eventually time out. I have concerns about this because it must have negative consequences for server scalability and performance.
The thing you are looking for is websocket https://en.wikipedia.org/wiki/WebSocket
Is there a general way to implement part of an application with JavaScript and supplying a persistent connection to a server? I need the server to be able to push data to the client, regardless of the client being behind a firewall. Thanks in advance
See Comet - it's like ajax, but it holds a connection open so the server can push information to the client.
Note that compliant browsers will only hold 2 connections (note: most modern browsers no longer comply) to a particular domain (by default), so you might want to split your domains (e.g. www.yourdomain.com and comet.yourdomain.com) so that you don't drastically slow down the loading of your pages. Or you could just make sure you don't open the comet connection until everything else is loaded. It's just something to be careful of.
You should look into Comet:
http://ajaxian.com/archives/comet-a-new-approach-to-ajax-applications
With HTTP, the connection has to start from the client. But there are techniques available for having the server hold the connection open and flush data as needed.
These are generally considered to be Comet or HTTP Streaming architectures.
You can use Comet programming techniques for this. Basically the page makes a call to the server that doesn't return until the server has something to send (at which point the client immediately makes the same call). This way the server can push content to the client pretty much whenever it wants.
Support varies depending on platform and is more an issue with the server than the client.
Here are a few questions in a similar vein. And of course all the questions tagged comet
Implementing a self resetting XMLHttpRequest object
Server-side Push in Rails
Is there an alternative of ajax that does not require polling without server side modifications?
Long-lived connections (asynchronous server push) with Apache/PHP/Javascript?