Skip to content

Instantly share code, notes, and snippets.

@jsjohnst
Created May 6, 2010 06:58
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jsjohnst/391878 to your computer and use it in GitHub Desktop.
Save jsjohnst/391878 to your computer and use it in GitHub Desktop.
var LongPuller = function() {
var internals = {};
internals.subscribers = {};
internals.xhrs = {};
internals.doXHR = function(key, url, errorTimeout, reconnectTimeout) {
var xhr = new XMLHttpRequest();
xhr.myCustomData = { key: key, url: url, errorTimeout: errorTimeout || 5000, reconnectTimeout: reconnectTimeout || 100 };
xhr.onreadystatechange = internals.handleResponse;
xhr.open("GET", url);
xhr.send();
internals.xhrs[key] = xhr;
};
internals.handleResponse = function() {
if(this.readyState != 4) { return; }
if(this.status == 200) {
internals.fire(this.myCustomData.key, { url: this.myCustomData.url, response: this.responseText });
sleep(this.myCustomData.reconnectTimeout);
} else {
sleep(this.myCustomData.errorTimeout);
}
internals.doXHR(this.myCustomData.key, this.myCustomData.url);
};
internals.stop = function(key) {
if(internals.xhrs[key]) {
internals.xhrs[key].abort();
}
};
internals.fire = function(key, value) {
if(!internals.subscribers[key]) {
log("No subscribers for '", key, "'!");
log(value.toSource());
return;
}
for (var index in internals.subscribers[key]) {
if(internals.subscribers[key][index] instanceof Function) {
internals.subscribers[key][index](value);
}
}
};
return {
start: internals.doXHR,
stop: internals.stop,
_subscribers: internals.subscribers
};
}();
// do our includes
var http = require('http'),
events = require('events');
// setup some local variables we need
var port = process.env.PORT || 8001,
dataStore = new events.EventEmitter(),
mostRecentStored;
// create our HTTP server which will listen for requests
http.createServer(function (req, res) {
// check to see if this is a store request, if it is, handle as such
if(req.url.indexOf("/store?") == 0) {
var query = require('url').parse(req.url).query;
mostRecentStored = query;
res.writeHead(200, {'Content-Type': 'text/plain'})
res.end('OK - ' + query);
dataStore.emit("store", query);
} else {
// see if we have a saved value which was never sent to a receiving client
if(mostRecentStored) {
// we have a saved value, so send it closing the connection
// then clear the variable so another request doesn't get it
res.writeHead(200, {'Content-Type': 'text/plain'})
res.end(mostRecentStored);
mostRecentStored = null;
} else {
// we don't have a saved value waiting, so we must wait for someone to store one
dataStore.addListener('store', function(value) {
// we got one! now send it to the client
res.writeHead(200, {'Content-Type': 'text/plain'})
res.end(value);
// we don't want to send the same value twice, so clear out the saved value
mostRecentStored = null;
});
}
}
// listen on the PORT defined in the environment or 8001 if not provided
}).listen(parseInt(port))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment