Long polling with jquery ajax()

This article focuses mainly on solving 3 problems:

  1. Apply long-polling technique using jquery ajax() function.
  2. Stop and restart long-polling when clicking on a UI element
  3. Prevent clicking too fast on the UI element

I am implementing an application with the requirement of being able to display a bunch of “real-time” data. Alright, real-time was exaggerated, I just need to update the display value every second. The long-polling technique (see also: push technology ) jumped to my mind at first. While a true push is not possible without the server side support, one can however emulate it using recursive ajax call with normal http request but with slower frequency.

(function longPolling(){
	$.ajax({
 		url: "server",
		dataType: "json",
		data: { param1:"param1", name:"name" }
		success: function(data, statusText, jqXHR){
			//processing data...
		},
	}).done(function(data, statusText, jqXHR){
		setTimeout(longPolling, 1000);
	});
})();

The code above will work. But the real requirement was that the old long-polling need to be stopped and start a new long polling immediately with new parameter when clicking on a new button or new folder or something. So I keep the parameter “name” which is in my case the clicked button/folder in the “lastClicked” variable and use it to control the long-polling:

var lastClicked, clicked;
$("#tree").fancytree({
	source: {
		cache: true,
		url: basePath + "type=devices",
		mimeType: "application/json; charset=utf-8"
	},
	click: function(event, data){
		clicked = data.node.title;
		if(lastClicked != clicked){
			(function longPolling(){
				if(!lastClicked || lastClicked===clicked){
					$.ajax({
	 					url: "server",
						dataType: "json",
						data: { param1:"param1", name:clicked }
						success: function(data, status, xhr){
							//processing data...
							lastClicked = clicked;
						},
					}).done(function(data, status, xhr){
						setTimeout(longPolling, 1000);
					});
				}
			})();
			lastClicked = "";
		}
	}
});

I used the jquery plugin fancytree to build a tree structure, and when I click on the tree element, I will get the title of the element which is the parameter of the long-polling call. You will see that the lastClicked variable will never be cleared within the longPolling() function, unless another click event starts.

The logic is described as follows:

  1. the long-polling will start only when a tree element was not clicked last time
  2. the long-polling will repeat only when there is no click on the new tree element

To prevent clicking too fast on the tree element, meaning, too many ajax calls start at a very short time, you need to add extra mechanism with new global variable processing, the solution below looks over-design, but I believe it’s necessary, because if the timeout is very short like 1ms period, the “precessing” variable will be set very frequently to true/false, so we need to invalidate the too fast clicks with “return false” to prevent the not awaiting behaviours like program hang:

var lastClicked, clicked, processing = false;
$("#tree").fancytree({
	source: {
		cache: true,
		url: basePath + "type=devices",
		mimeType: "application/json; charset=utf-8"
	},
	click: function(event, data){
		if(processing==true){
			// prevent clicking to fast
			return false;
		}
		clicked = data.node.title;
		if(!processing && lastClicked != clicked){
			(function longPolling(){
				processing = true;
				if(!lastClicked || lastClicked===clicked){
					$.ajax({
 						url: "server",
						dataType: "json",
						data: { param1:"param1", name:clicked },
						success: function(data, status, xhr){
							// processing data...
							lastClicked = clicked;
						}
					}).done(function(data, status, xhr){
						processing = false;
						setTimeout(longPolling, 1000);
					});
				}
			})();
			lastClicked = "";
		}
	}
});

In fact, I hate so many global variables. If you have better idea the fix this, please don’t hesitate to tell me, thanks in advance. 🙂

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.