Tuesday, June 6th, 2006

IFrame + Script Tags = Portable Comet

Category: Comet, Examples, IE, Office, XmlHttpRequest

<p>In a recent post, I explain the difficulties of Comet (Streaming/Push) in IE.

IE makes it difficult for two reasons: (a) IE’s XMLHttpRequest component doesn’t tell you anything about the response until the connection has closed – even if you try polling it instead of relying on onReadyStateChange, you’ll still get an empty string (Try it); (B) Okay, switch to plan B and inspect IFrame content – we can’t rely on onload, which is only called once at the end, so we *must* poll. But no, polling won’t help either, as the IFrame content remains empty until (you guessed it) the connection is closed. (Try it).

Fortunately, there *is* a portable solution, demonstrated here.

The portable solution is this: Have the server continuously output script tags that call a known function in the parent frame. When you set the child IFrame’s source to point to this service, it will start evaluating the inline scripts as they pop out of the server.

Of course, none of this is really new, at least not to some people. Ajax pioneer Brent Ashley points out:

The ReadyState 3 issue that Michael talks about has been well known (well, apparently not well known) at least since Scott Andrew LePera described the problem in late 2002. It really needs to be fixed.

Hopefully, future versions of IE will expose the ongoing response while the XHR connection is still open. But until then, we at least have a workable technique that works across different browsers.

This area isn’t very well-documented; It would be good to hear what others have done to make streaming portable.

Related Content:

Posted by Michael Mahemoff at 4:33 pm
24 Comments

+++--
3.9 rating from 63 votes

24 Comments »

Comments feed TrackBack URI

For ICEFaces we are using a heartbeat mechanism that monitors and keeps the connection alive: http://www.icesoft.com/products/icefaces_enterprise.html

Comment by Mircea Toma — June 6, 2006

OK, this is so 1999. I tried this back then, only problem being that it not scalable in PHP. So I actually reverted it back to a polling mechanism (I just had the hidden iframe reload rather than pause and wait on the server side). Nice that you could use mostly the same code to do it either way, though. But really, it was great holding the socket open in a test environment, and to show how cool it was (in 1999). But to have thousands (tens of thousands, actually) using it is to have that many PHP processes running simultaneously. Blah! Ick! Yuck! $$$!

Comment by Steven Roussey — June 6, 2006

Sigh. I get tired of this.
One has to remember that the original MSXML parser (i.e. XMLHTTPRequest) was intended to be used in places other than in script–as in C++ and VB, both of which could read IStream objects and actually *do* something with the incoming responseStream or responseBody while it is being filled, both of which represent a stream of bytes which may or may not be complete.

We as part of the scripting community need to remember that not everything is perfectly accessible from script, nor are certain things originally designed to work that way.

Not everything is accessible from script, you know.

Comment by Tom Trenka — June 6, 2006

And no offense, but you guys *really* need to fix the comment system here. Nothing worse than submitting a comment and ending up at an apparently blank page…

Comment by Tom Trenka — June 6, 2006

I did some fiddling around with this a while back, trying to do a multi-client chat thing with a broadcast socks server. It worked, but the whole thing is pretty experimental. I tried to explain the technique as well. Enter some junk name and then up your font size. ;)

http://www.schillmania.com/projects/rpc-js/

Comment by Scott Schiller — June 6, 2006

Pardon the double-comment. Here’s a link directly to the code involved, with some technical explanation.

http://www.schillmania.com/projects/rpc-js/rpc-js.js

I think Google is using a somewhat similar approach with Gmail (as Alex Russell covered several months ago,) and while it works, I think it’s a crazy hack. A technical feat mind you, but still – actually being used in a large-production site? – woah! :)

(Then again, we used to say that about Javascript animation.)

Comment by Scott Schiller — June 6, 2006

I did something similar, Scott, using a hand-rolled web server that multiplexed connections to avoid running a huge number of CGI processes just to send data out. There was a “control socket” that other local processes could connect to “dispatch” additional data to any one (or all) of the listening clients.

Not everything needs to be done using CGI and stateless HTTP — use HTTP to initiate the connection, (since that’s what the browser talks), but then hand the whole thing off to custom code.

Comment by Andy — June 6, 2006

It’s funny how the popularity of the web browsers as an application development environment brings back old problems as new. I think i solved this in 2000. In any case, if you’re using Javeline TelePort or Javeline FrameWork this solution is in there.

Comment by Ruben — June 7, 2006

[...] Ajaxian has a great little post (”IFrame + Script Tags = Portable Comet“) about IE and Comet and how they don’t play nice together yet. But, they also mention that there is a (hack hack) workaround. It uses IFrame and script tags. [...]

Pingback by » Internet Explorer (IE) Gets Hit by a Comet :: Nate Ritter :: — June 7, 2006

@Tom and @Ajaxian: Yep, they NEED to fix the commenting system… I can’t believe this is still not working properly. That, and the shear volume of worthless posts is getting me pretty close to deleting this feed.

Comment by Ryan Gahl — June 7, 2006

[...] Ajaxian OfficeTheir vision is to be a complete, fully functional MS Office clone on-line. They let you import Excel and Word and other formats into their products. Michael Arrington: You guys have a reputation of [...]

Pingback by Office » Office Furniture | Office Chairs | Home Office Furniture — June 7, 2006

Does anyone have any data on server performance with polling vs. comet to push data from a server? On a production system with 100′s of users ould it be better to do an AJAX request every 5 seconds to look for an update from the server or do the iframe hack to keep a connection open? The Comet/iframe method worries me if there are 100′s of open connections to the server that aren’t closing. But at the same time, pounding the server by 100′s of users every 5 seconds doesn’t seem happy either. What are your thoughts on performance between these two methods?

Comment by Jeremy — June 7, 2006

Jeremy,

It depends how the connections are managed. If you are allocating a spare thread for them, then polling will perform better. But if you implement it correctly, with minimal resources allocated, you should be able to keep several thousand sockets open without too much problem.

I haven’t actually done it mind you — but in theory that’s how it should work ;)

Comment by Ben Joldersma — June 7, 2006

Keeping sockets open in Java is much easier to do than, say, PHP, where you are totally out of luck (well, you could use both, I suppose). I’m not sure what Ruby and others provide.

Comment by Steven Roussey — June 7, 2006

…and you’re all just fine with Ajaxian’s commenting system?

At the very least you could all do your normal post, and then make another post pointing out that the commenting system sucks. I think then they might get it. Maybe. Probably not, it’s been broken forever so why would they fix it now?

Oh well, at any rate I can take comfort in knowing where I can find a completely blank page on the internet. Just gotta make a post on Ajaxian.

Comment by Ryan Gahl — June 7, 2006

This is the exact technique that CGI:IRC uses. It has worked pretty well in most browsers (and it has hardly needed changing since I wrote in late 2002!).

Comment by David Leadbeater — June 7, 2006

David,

If CGI:IRC is using push, how come i don’t see the loading indication for the lifetime of the page? How did you get around that?

Thanks,
Tal.

Comment by Tal Broda — June 10, 2006

One big problem with pushlets (or IFrame and scripts tags) is that the browser (at least IE) reads everything into memory, never releases it and eventually slows down PC to a halt. After all its just one huge page for all it knows.
It may work well for low traffic and/or short-lived sessions, but leave it for a few days or try it on a high volume data stream and you’ll see what I mean.

Comment by Gregory — June 14, 2006

Gregory – true, however a call to a Javascript function to loop through the DOM to remove those script tags that have arrived from the server should sort that.

Comment by Nutz — June 17, 2006

Nutz – I don’t remember if I tried it back when I played with this idea, so I tried it again, and alas, it makes no difference in the memory usage. Whether you remove every script tag as soon as it’s processed or not, the memory keeps growing.

Comment by Gregory — June 19, 2006

I purly love this aproach, but im looking for a demo that uses same connection to send and revice data, is this possible? Anyone seen a example of this?

Im looking for an example:

Explenation:
1.Create a long lived http connection, attach a listener on server side for incoming msg (preferable java or php).

2.Click on a button on the page, that uses the already establish connection and send “hi” to the server, the server responed on the same connection channel with “hello there”.

Comment by Kvark — June 27, 2006

[...] Ajaxian OfficeTuesday, June 6th, 2006. IFrame + Script Tags = Portable Comet. Category: XmlHttpRequest , Examples , IE , Office , Comet. In a recent post , I explain the difficulties of Comet (Streaming/Push) in IE [...]

Pingback by Office » Ajaxian Office — July 31, 2006

It’s a fair point…Alex’s original Comet article doesn’t only talk about streaming, but also about a distributed event model (as in Twisted). I guess the JSON-P method is a kind of Comet-lite.

Comment by David law — July 9, 2007

Orbited: http://brbx.com/orbited

Orbited is a comet daemon that works on many platforms for many languages. It supports comet style long-polling as well as Iframe streaming. It also has a clear scaling path.

Comment by Michael Carter — August 8, 2007

Leave a comment

You must be logged in to post a comment.