This question is really similar with this question:What is the difference between web sockets, long polling, server-sent events and forever frame?
However, this question's answer doesn't mention the difference between SSE and Forever-frame.
Let me give you brief explanation about them.
Regarding to SSE, the system really resembles Comet, but the point which is different with Comet is not breaking the connection after data being sent.
So, connection from a server to a client is long-alive and the client receives series of fragments of a whole data.
On the other hand, forever frame seems to be very similar to me. In Forever frame, first the client receives the page including an iframe tag, establishing a long-lived connection inside the hidden iframe. And then the client receives chunked datas from the server and manipulates the DOM with some functions on the first document the client already has.
I assume the difference is Forever-frame uses iframe tag in the mechanism, but SSE doesn't and SSE can be realized by more ways.
Am I right?
I'd not heard of Forever-frame by that name before! (It is covered in ch.7 of my book, Data Push Apps with HTML5 SSE, in the "iframe" section).
Long-polling: make a request (using XMLHttpRequest, i.e. ajax), keep it open until the data is ready on the server. Then the socket closes. Re-connect to get the next bit of data.
XHR polling: make a request (using XMLHttpRequest2, i.e. ajax), but listen in to the readyState==3 signals. The back-end server has to know to keep the connection open, and the client has to know to listen to readyState==3. (Does not work in IE9 and earlier, because that browser never delivers the readyState==3 messages, but goes straight to readyState==4)
iframe: open a hidden iframe to the back-end process. Regularly go look at the source code of the iframe, and see if anything new is there. (Technically it works on all browsers, but IE8 and IE9 were the only ones in my (2013) tests with low enough latency for the updates to be useful.)
SSE: An HTML5 standard that basically works like XHR polling (Firefox and Chrome, at least, implement it directly on top of XMLHttpRequest2), but with the complex details hidden from you. It also adds auto-reconnect if the socket goes down, and a few other high-level features like that.
At the end of chapter 7 of the afore-mentioned book, I show code to get all the techniques to work in just about any browser. The order of preference is:
SSE if available
else XHR if available
else iframe if IE8 or IE9
else longpoll
There is one other difference: the XHR and iframe techniques are storing the entire message history in memory. So, if you intend to keep the socket open for a long time and/or send a lot of large messages, this may cause a memory issue that wouldn't happen with SSE.
Executive Summary: Don't worry about "forever-frame" unless you have enough customers still using IE8/IE9 that the longpoll approach would create noticeable additional load on your infrastructure.
SSE is not really an option because of lack of browser support, so the answer to your question is ....
I assume the difference is Forever-frame uses iframe tag in the
mechanism, but SSE doesn't and SSE can be realized by more ways
no.
iframe is actually the easiest to implement and has the least overhead. The only drawback is memory use over time.
XHR is very clean and efficient, but has some IE version limitations. If you have users still using those versions of IE, they probably won't have any use for an application with real-time messaging :)
You could always just use:
<script>
window.setTimeout(poll, 3000);
function poll() {
$.ajax({
url: "/",
type: "POST",
data: {},
dataType: "json",
traditional: true,
contentType: "application/json; charset=utf-8",
success: function (data) {
// do something
},
error: function () {
// handle it
},
complete: function() {
window.setTimeout(poll, 3000);
}
});
}
Related
I know I should probably use WebSockets or Server-Side Events, but what happened to the Comet Streaming techniques that involved writing chunked data from a server to either an iFrame or as a response to a xmlHttpRequest? I have stumbled upon multiple demos but none of them work as intended any more and since most of the material on this type of streaming is quite old, I'm wondering whether or not it is still doable in the year of 2015?
Just to be clear, I'm referring to the Comet techniques where the server keeps a connection open using chunked transfer encoding flushing new data on the fly. Incremental rendering in browsers should presumably make this data available, either as it comes in in the case of an iFrame (e.g. "Forever iFrame") or by reading the responseText property of the xmlHttpRequest object when its readyState returns 3 (e.g. "XHR streaming"). However, all browsers seem to buffer the data until the connection is closed, no matter how much bogus preamble I add before starting to send real data. Also, I'm not referring to the special case with Content-Type set to multipart/x-mixed-replace which works in Firefox only, but an approach which seems to have worked on most of the browsers a few years back.
Does anyone know if current browser behaviour has obsoleted these Comet streaming techniques?
Example demos:
Polling responseText on load through xmlHttpRequest object:
http://ajaxify.com/run/streaming/xmlHttpRequest/countdown/
http://ajaxify.com/run/streaming/xmlHttpRequest/
Slow loading of regular page, incremental rendering does NOT kick in for me:
http://ajaxify.com/run/streaming/
Polling iFrame content on slow iFrame load:
http://ajaxify.com/run/streaming/xmlHttpRequest/iframe/
These demos does not use chunked transfer encoding but resulting behaviour is the same, that is, incremental rendering isn't happening.
Article on Comet streaming:
http://cometdaily.com/2007/11/05/the-forever-frame-technique/
Short version conclusion:
All the Comet techniques still work, however, in my case the antivirus got in the way of things in an unforeseen manner so make sure to test things on different computers and in safe mode as well to be sure if it doesn't work!
I've recently stumbled upon multiple talks claiming that you should start responding to any incoming HTTP request ASAP, which seems reasonable, but I'm not clear on how to communicate failure when employing this strategy.
Let's image the situation where we send a response code of 200 and start rendering a HTML page. As we construct the body, the data flows in from various db queries and suddenly an error occurs. It's a bit too late to change our mind at this point in time.
Or maybe a more practical example:
We're providing an API that potentially delivers a lot of data. To keep it fast, we stream the data off the DB connection through some project function and then into a streaming JSON encoder that writes right to the socket. And poof, something goes wrong. DB connection breaks up, reconnection attempts time out. We've just flushed 100K JSON objects, but the result set was actually bigger than that.
Is there any good way to die gracefully half way into an HTTP response?
In the HTML case, one could always print some human readable information. And in the API, once can respond with { "results": [ /* payload goes here */ ], "error": { /* error information */ } }, which is ok, since the error is written after the payload. But ideally I would like to use something built into the HTTP protocol. It seems weird to say 200 and then deliver an error. Is there a better way?
Once the status code is sent the only option you have is closing the connection.
Is there any good way to die gracefully half way into an HTTP
response?
No, if you flushed http status to client - there is no possibility to change it, so the only approach is to generate output fully on server and then start streaming it to client with proper http code
NOTE - checkout gzip compression for big JSON data
I do understand the basic idea of it. But most of the implementations I've seen have done nothing but confused me - I find myself incapable of fully understanding the concept of Comet and long polling... Simply put, I ask for simple explanation of these ideas. I am especially interested in an explanation of the hidden iframe polling technique. What gets executed, what gets requested etc.
Also, what are the advantages of it over the classic ajax approach? (besides the reduced traffic and more real-time feeling).
Thanks.
The technique is very nicely explained in the following article. The core idea resides on the chunked transfer encoding HTTP technique. A hidden iframe is included in the page which points to a server side script which uses chunked encoding. In chunked encoding the response is not sent entirely in one go and the stream closed. The server doesn't say in advance how much data is going to send so the browser keeps the channel open. Then when the server wants to push some data to the client it simply sends a chunk of response which represents a javascript function. The browser receives and executes this function on the client. This way the server can successfully PUSH information when some events occur like for example some data changes on the server, ...
Also, what are the real advantages of it over the classic ajax
approach? (besides the reduced traffic and more real-time feeling).
Aren't those advantages sufficient? Reduced traffic means more responsive application. Did you know that large sites like Google and Amazon conducted studies and explicitly throttled down their servers in order to increase the response time with a couple of milliseconds. I can't remember the exact but they were flagrant: they lost like 70% of their customers after doing that. Remember: the most important feature of a web application (and not only by the way) is its responsiveness.
So it's basically PULL (Ajax) vs PUSH (Comet). PUSH techniques scale better when the number of clients starts to increase.
In general chat application, client's browser always poll to server to check for new messages.
// the function to check new messages in server
function check(){
// but this question is less about jQuery.
$.ajax({
type: "POST",
url: "check.aspx",
data: "someparam=123",
success: function(msg){
// process msg here
// CHECK IT AGAIN, but sometimes we need to make delay here
check();
}
});
}
Then I read Nicholas Allen's blog about Keeping Connections Open in IIS.
It makes me think if it is possible to push data from my server to client's browser by transfer chunked HTTP (it means like streaming, right?) and keep the connection open.
while keeping the connection open, in server, I have idea to keep something run to check new messages. something like this, maybe
while(connectionStillOpen) {
// any new message?
if( AnyMessage() )
{
// send chunked data, can I?
SendMessageToBrowser();
// may be we need to make delay here
Sleep(forSomeTime);
}
}
that's a raw idea.
My Chat App created in ASP.net. With my less understanding of WCF and advanced IIS streaming module, I need your advice about to implement this idea.
yea, Impossible is probably the answer. But I need to know why if its still impossible.
UPDATE (3 years later):
This is exactly what I was looking for:
Microsoft ASP.NET SignalR
Yes, it's impossible to push data from server directly to your browser client.
But you can to check server for new messages every, let's say, 3 seconds and refresh your client interface.
Maybe you want to take a look on some Comet implementations
A server cannot initiate communication with the client. So the server cannot push data to the client. But you can achieve the push mechanism using "Reverse AJAX". The following article should shed more light.
Reverse AJAX
One method is there which is called Reverse AJAX. By using which server can transfer data to client without any request from the Client.
The current generation of JavaScript / Ajax libraries don't provide access to partial responses; you only receive notification when the entire request is complete.
If you're open to using Silverlight, you can use a raw TCP connection.
Comet is another option -- but that's basically just long polling that still originates from client-side script.
Its not possible to push the data from the server. Because HTTP respond only to the requests and cannot contact the client directly. But we have a workaround here called COMET or ReverseAJAX, by using this technique we can simulate the duplex calls.
Its nothing but the long living AJAX
calls, and will respond to the client
if there is a expected event happening
in server side, otherwise it stays
calm. This Comet (programming)
wikipedia article explains more about
the approach
I have answerd similar question here asp-net-chat-with-wcf. pls check out
I'm sure Wave doesn't poll the server every millisecond to find out if the other user has typed something... so how can I see what the other person is typing as they type? And without hogging the bandwidth.
Persistent HTTP, Comet
Keep your HTTP connection alive and send characters as they are typed
*Edit in 2014: also, take a look at WebSocket and HTTP/1.1 Upgrade header. Browsers started implementing this around 2010, so I'm adding this to original answer.
They probably use Web Sockets, aka server-sent events: http://www.w3.org/TR/websockets The underlying protocol can be found (as a draft) at the IETF.
Update: it doesn't seem WebSockets has any implementation yet; and a video from Google I/O (go to 11:00) talks about a long lived HTTP GET request.
Server Push in GWT
Server push is the Wait, Respond, Close, Re-Open paradigm:
Wait: When the GWT code makes a call
to your server for some data that you
don't have yet, freeze (wait)
Respond: Once the requested data is
available, respond with it
Close: Then, close the connection.
Re-Open: Once your GWT code receives the response, immediately open up a new connection to query for the next event.
See Video Google Wave: Powered by GWT around at minute 55 (near the end)
Q: How you implement the persistent Connections, the long living http connections
A: Future Plan: HTML5 Web Sockets. Longer term. That's what we use at the moment.
Q: Is there a platform or library for this we can download and play with?
A: Not sure. Don't think so
P.S.: That's what he said. To me it did not make much sense ("future plans" vs "using at the moment"). Any native english speaker might want to verify if I transcribed it correctly?
Pure speculation but could it be using the Server Side DOM events from the HTML 5 spec?
the entire reason for WebSockets is to have the browser keep a bi-directional socket open to a server so that real time communications can be used. When someone types on the other end, in a wave client, it triggers an event that is sent to the server and the server in turn looks to see who should also receive the event and pass them the event, in this case the typed letter.
WebSocket and Comet are different.
Granville
Probably comet for now websocket in the future. Because it works in Firefox 3.5 and from what I've read the websocket is only available in the nightly builds of FF... I could be wrong though... as it appears to not work in IE at all.
I spent some time reverse-engineering the Google Wave client code (shameless plug for http://antimatter15.com/misc/read/ which is a read-only public client for google wave for all public waves without need of robots or gadgets which was a lot more useful a month ago when Google didn't launch the upgrades).
Anyway, Google uses the GWT framework with certain aspects of the Google Closure library (which is actually open source and documented) and they use the goog.net.BrowserChannel library, which from the comments is also used for chat functionality within gmail.
http://closure-library.googlecode.com/svn/docs/closure_goog_net_browserchannel.js.html
I would assume that they use ajax requests. Do an XMLHttpRequest, which is asynchronous, and when the server has something to send your browser the javascript callback that was registered gets the data and does whatever with it. So basically the browser requests the next event, handles it, repeats indefinitely.