Navigation Menu

Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Robert Righter committed Dec 24, 2009
0 parents commit 8d97881
Show file tree
Hide file tree
Showing 4 changed files with 755 additions and 0 deletions.
72 changes: 72 additions & 0 deletions README.md
@@ -0,0 +1,72 @@
Long Polling Buffer
===================

(C) Rob Righter (@robrighter) 2009, Licensed under the MIT-LICENSE

A Library for Node.js to simplify AJAX long polling

API
---

### LongPollingBuffer(buffersize)

Constructor. Initializes the buffer to be of size buffersize

### push(value)

Pushes data onto the queue which in turn notifies all the listeners

### addListenerForUpdateSince(since, callback)

Adds a listener for data updates. The callback is triggered when data is available after the since.


Example usage: Simple Activity Monitor
--------------------------------------

var fu = require("./lib/fu");
var sys = require('sys');
process.mixin(GLOBAL, require("./lib/underscore"));
var lpb = require("./lib/longpollingbuffer");

HOST = null; // localhost
PORT = 8000;

//helper function
String.prototype.trim = function() {
return this.replace(/^\s+|\s+$/g,"");
}

// Now start the program
fu.listen(PORT, HOST);
var rb = new lpb.LongPollingBuffer(200); //Create the Long Polling Buffer
var iostat = process.createChildProcess("iostat", ["-w 1"])


//Setup the listener to handle the flow of data from iostat
iostat.addListener("output", function (data) {
sys.puts(data);
if(data.search(/cpu/i) == -1){ //suppress the column header from iostat
rb.push(data.trim().split(/\s+/).join(" "));
}
});

//Setup the updater page for long polling
fu.get("/update", function (req, res) {
res.sendHeader(200,{"Content-Type": "text/html"});
var thesince = parseInt(req.uri.params.since);
if(!thesince){
thesince = -1;
}

rb.addListenerForUpdateSince(thesince, function(data){
var body = '['+_.map(data,JSON.stringify).join(',\n')+']';
res.sendBody( body );
res.finish();
});
});

// Static Files
fu.get("/", fu.staticHandler("./client-side/index.html"));
fu.get("/css/site.css", fu.staticHandler("./client-side/css/site.css"));
fu.get("/js/site.js", fu.staticHandler("./client-side/js/site.js"));
27 changes: 27 additions & 0 deletions example.js
@@ -0,0 +1,27 @@
var sys = require('sys');
var un = require("./lib/underscore");
var lpb = require("./lib/longpollingbuffer");

var rb = new lpb.LongPollingBuffer(8);

rb.push("I'm");
rb.push('affraid');
rb.push('the Death Star');
rb.push('will be');
rb.push('fully');
rb.push('operational');
rb.push('when');
rb.push('your');
rb.push('friends');
rb.push('arrive');


//Since forever (or to the size of teh buffer)
rb.addListenerForUpdateSince(-1, function(data){
sys.puts('\n\nSince forever (or to the size of the buffer): \n' + _.map(data,JSON.stringify).join(',\n') );
});

//Since offset 6
rb.addListenerForUpdateSince(6, function(data){
sys.puts('\n\nSince offset 6: \n' + _.map(data,JSON.stringify).join(',\n') );
});
47 changes: 47 additions & 0 deletions lib/longpollingbuffer.js
@@ -0,0 +1,47 @@
var sys = require('sys');
var un = require("./underscore");

//the readbuffer provides a databuffer with a moving offset that can be used to allow AJAX long polling (instead of the websocket)
function LongPollingBuffer (buffersize) {
this.data = new Array();
this.size = buffersize;
this.offset = 0;

function BufferItem (offset,value) {
this.offset = offset;
this.value = value;
}

this.push = function(value) {
this.data.unshift(new BufferItem(this.offset++,value));
while(this.data.length > this.size){
this.data.pop([]);
}
this.emit('newdata',this.data);
}

this.datasince = function(since) {
return un._.select(this.data, function(item){ return item.offset>since; });
}

this.addListenerForUpdateSince = function(since, callback) {
response = this.datasince(since);
if(response.length==0){
//no data yet pass off the callout to wait for it
this.addListener('newdata', function(thedata){
callback(this.datasince(since));
});
}
else {
//send back the data
callback(response);
}
}
}

LongPollingBuffer.prototype = new process.EventEmitter();


process.mixin(exports, {
LongPollingBuffer: LongPollingBuffer
});

0 comments on commit 8d97881

Please sign in to comment.