Server push, jquery atmosphere and the throbber of doom

February 3, 2011 by Michael

I’m using the Atmosphere framework to implement server push (a.k.a. Comet) in a Spring 3 application.

Atmosphere includes a fine jQuery plugin to handle the client side code. The plugin works quite well and Jean-Francois, the author, has a good tutorial in his blog: Using Atmosphere’s JQuery Plug In to build applications supporting both Websocket and Comet.

The code works but causes webkit browsers (Chrome and Safari) to show the throbber (that little spinning thingy in tab or address bar). In iOS browsers that loading progress bar will not disappear.

I found some suggestions to get rid of the “throbber of doom” but none of them worked for me.

So here is my solution which is tested with jQuery 1.4.2 and jQuery.atmosphere 0.6.3:

<script>  	
	// See https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind
	if(!Function.prototype.bind) {
		Function.prototype.bind = function( obj ) {
			var slice = [].slice,
			args = slice.call(arguments, 1), 
			self = this, 
			nop = function () {}, 
			bound = function () {
				return self.apply( this instanceof nop ? this : ( obj || {} ), args.concat( slice.call(arguments) ) );    
			};
 
			nop.prototype = self.prototype;
			bound.prototype = new nop();
			return bound;
		};
	}
 
	var subscribe = function() {		 	
		$.atmosphere.subscribe(
			'/subscription/url',
			function(response) {				
				$('body').append(response.responseBody + '<br>');						
			},
			$.atmosphere.request = {								
				transport: 'websocket',
				fallbackTransport : 'long-polling'
			}
		);
	};
 
	$(window).load(function() {				
		setTimeout(subscribe.bind(document),500);
	});
</script>

The trick is: Wait for the whole page to be loaded (including all resources) by using $(window).load instead of $(document).ready. Then set a timeout to your subscription function. The timeout will change the execution context of the function to the global object (in most cases window). This needs to be corrected to the document for the atmosphere jQuery plugin to work. Here comes bind() to the rescue. This is a Javascript 1.8.5 function and it is not available in all browsers (see bind) and therefore added to the prototype.

So far i’ve tested this in Firefox 3.6, Chrome 8, Safari 5 and Internet Explorer 8 and had no problems.

No comments yet

Post a Comment

Your email is never published. We need your name and email address only for verifying a legitimate comment. For more information, a copy of your saved data or a request to delete any data under this address, please send a short notice to michael@simons.ac from the address you used to comment on this entry.
By entering and submitting a comment, wether with or without name or email address, you'll agree that all data you have entered including your IP address will be checked and stored for a limited time by Automattic Inc., 60 29th Street #343, San Francisco, CA 94110-4929, USA. only for the purpose of avoiding spam. You can deny further storage of your data by sending an email to support@wordpress.com, with subject “Deletion of Data stored by Akismet”.
Required fields are marked *