powered by Google

Comet (long polling) for all browsers using ScriptCommunicator

Posted on 28. Jan · Comments [7]
Plurk Comet

There's little information on the web how to implement comet (long polling) so it works across domains and works in all major browsers.

I am sharing my solution that's used to power comet on Plurk and I hope this can save time for anyone that has to implement something similar.

I have pushed ScriptCommunicator on github and this script can do following stuff:

  • uses script tags for communication, but can detect when a script isn't loaded (this is non-trivial to implement across browsers)
  • works across domains as long as you control the domains
  • works on IE 6, IE 7, IE 8, FF X, Safari, Chrome and Opera
  • small (80 lines of code) with no dependencies

ScriptCommunicator can also be used to do JSONP calls in a manner where you can handle errors properly. ScriptCommunicator is copyrighted by Plurk Inc. and released under the BSD license.

The problem

There are different problems associated with long polling:

  • scaling comet by using one domain is a lot more difficult than scaling it by using different domains
  • most browsers limit how many open connection you can have to one domain
  • AJAX communication between different domains is restricted due to same origin policy

To solve this we use script tags for communication and this has one big pitfall: you can't easily find out whatever a script is sourced properly - - so error handling using script tags becomes a lot more difficult. ScriptCommunicator adresses these issues and makes communication easy.

The hack

It's trivial to source scripts across domains (you simply append the SCRIPT tag to the head or the body). What's not trivial is finding out if the script was sourced properly and handling errors - and I haven't found a solution for this problem on the net. But there is a solution and it works like this:

  • for Internet Explorer we use script_tag.onreadystatechange to figure out if a success signal is set
  • for other browsers we use following knowledge: sourcing JavaScript is blocking, this means we append two script tags to the document where the first one is sourcing the JavasScript and the second one checks if a success signal is set

It's hacky, but it works :-)

How to use it

You source JavaScript from another domain and this domain does a callback to foocall function. You also supply two functions on_success and on_error.

var url = 'http://some_domain.com/give_me_js_back.php?i=42&callback=foocall'
ScriptCommunicator.sourceJavascript(url, on_success, on_error)

Either your external JavaScript or foocall sets following attribute to true (to signal that the loading of the script was succefull):

ScriptCommunicator.callback_called = true;

That's basically it! Visit ScriptCommunicator on github to get the code.

If you are interested in comet check out following amix.dk posts:

Like this post? Subscribe to the RSS feed!
7 comments so far

Thanks Amir!
I have been wanting to look into the Comet paradigm, just didn't have any good place to start :)

Thanks Amix - it's something I was just about to work on.
Looks really good.

( quick fix to the above code, 'S' in sourceJavascript should be uppercase: 'sourceJavaScript' )

Any chance of a demo page? I've found this as a potential solution to what I'm trying to do, but having never done it before, I don't quite get it from your description. :)

K_l_oJI

Is an iframe needed for Safari/webkit?

Very interesting, this really hard to know.

Post a comment
Commenting on this post has expired.
© 2000-2009 amix. Powered by Skeletonz.