Created
July 2, 2012 15:26
-
-
Save eabait/3033778 to your computer and use it in GitHub Desktop.
REST Service Poller based on Web Workers and XMLHttpRequest object
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var Ajax = { | |
httpRequest : null, | |
initXmlHttpObject : function() { | |
'use strict'; | |
if (XMLHttpRequest) { // Chrome, Mozilla, Safari, ... | |
this.httpRequest = new XMLHttpRequest(); | |
} else | |
if (ActiveXObject) { // IE | |
try { | |
this.httpRequest = new ActiveXObject("Msxml2.XMLHTTP"); | |
} | |
catch (e) { | |
try { | |
this.httpRequest = new ActiveXObject("Microsoft.XMLHTTP"); | |
} | |
catch (e) {} | |
} | |
} | |
}, | |
sendRequest : function(config) { | |
'use strict'; | |
if (!this.httpRequest) { //reuse the same object | |
this.initXmlHttpObject(); | |
} | |
var req = this.httpRequest; | |
if (!req) { | |
return; | |
} | |
req.open('GET', config.url + '?' + this.stringifyParams(config.options), true); | |
//req.setRequestHeader('User-Agent','XMLHTTP/1.0'); | |
req.onreadystatechange = function() { | |
if (req.readyState !== 4) { | |
return; | |
} | |
if (req.status !== 200 && req.status !== 304) { | |
config.error(); | |
return; | |
} | |
config.success(req); | |
}; | |
if (req.readyState === 4) { | |
return; | |
} | |
req.send(); | |
}, | |
stringifyParams : function(params) { | |
'use strict'; | |
var keys = Object.keys(params), | |
i, | |
l, | |
s = [], | |
value; | |
for (i = 0, l = keys.length; i < l; ++i) { | |
value = (params[keys[i]] == null) ? '' : params[keys[i]]; | |
s[s.length] = encodeURIComponent(keys[i]) + '=' + encodeURIComponent(value); | |
} | |
return s.join('&').replace(/%20/g, "+" ); | |
} | |
}; | |
var Poller = (function() { | |
'use strict'; | |
return { | |
// number of failed requests | |
failed: 0, | |
// starting interval (1000 === 1 second) | |
interval: 10000, | |
timer: null, | |
url: null, | |
options: null, | |
// kicks off the setTimeout | |
init: function(){ | |
if (this.timer) { | |
clearTimeout(this.timer); | |
} | |
this.timer = setTimeout( | |
this.getData.bind(this), // ensures 'this' is the poller obj inside getData, not the window object | |
this.interval | |
); | |
}, | |
stop: function() { | |
clearTimeout(this.timer); | |
}, | |
// get AJAX data + respond to it | |
getData: function(){ | |
Ajax.sendRequest({ | |
url: this.url, | |
options: this.options, | |
success: this.successHandler.bind(this), | |
error: this.errorHandler.bind(this) | |
}); | |
}, | |
successHandler : function(res) { | |
self.postMessage(res.response); | |
this.init(); | |
}, | |
// handle errors | |
errorHandler: function(){ | |
if( ++this.failed < 10 ){ | |
// give the server some breathing room by | |
// increasing the interval | |
this.interval += 1000; | |
// recurse | |
this.init(); | |
} | |
} | |
}; | |
}()); | |
//Handle communication with web worker | |
self.addEventListener('message', function(e) { | |
'use strict'; | |
var data = e.data; | |
switch (data.cmd) { | |
case 'start': | |
Poller.url = data.url; | |
Poller.options = data.options; | |
Poller.init(); //start polling | |
break; | |
case 'stop': | |
Poller.stop(); //clears the timeout | |
self.close(); // Terminates the worker. | |
break; | |
case 'updateConfig': | |
if (data.url) { | |
Poller.url = data.url; | |
} | |
if (data.options) { | |
Poller.options = data.options; | |
} | |
break; | |
default: | |
self.postMessage('Unknown command: ' + data); | |
} | |
}, false); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment