Current




          @robrighter
What is Node.js?

_ non-blocking
_ evented
_ javascript




                   @robrighter
Why is node useful?




                      @robrighter
Why is node useful?

It can handle a ton of
concurrent connections




                      @robrighter
A Gross
Oversimplification
of HTTP


              Give me a page




                    Sure




             Connection Closed



                                 @robrighter
AJAX Polling

               Got any updates?


                      No


               Connection Closed


               Got any updates?


                      No


               Connection Closed
                                   @robrighter
Comet

        Got any updates?



            ...wait



              Yes



        Connection Closed




                            @robrighter
Websocket




            asyncronous updates




                                  @robrighter
Evented Programming




                      @robrighter
Non-Evented Example

mysql_select_db("example", $con);
$result = mysql_query("SELECT * FROM user WHERE fname='Bill'");

while($row = mysql_fetch_array($result)){
    echo $row['fname'];
}




                                                   @robrighter
Evented Example

fs.readFile("./file", function (err, data) {
  if (err) throw err;
  sys.puts(data);
});




                                  @robrighter
An Example




             @robrighter
Server Side




              @robrighter
Setup the Data Source
var rb = new lpb.LongPollingBuffer(70);
var dump = process.createChildProcess("tcpdump",["-i","en1","-A","-n","port", "80"]);
var ignorelist = ['localhost','foxnews.com'];

//Setup the listener to handle the flow of data from the dump
dump.addListener("output", function (data) {
    var hosts = data.match(/Host: (.*)/g);
    if(hosts){
        _.each(hosts, function(item){
            var out = item.slice(6);
            sys.puts(out);
            if(!_.detect(ignorelist, function(s){ return (item.indexOf(s) > -1); })){
                rb.push(out);
            }
            
        });
    }
});




                                                                    @robrighter
LongPollingBuffer
                                   DATA ARRAY

 DATA:    1      1         1   0       1    0       0     1          1   0
OFFSET:   0      2         3   4       5        6   7     8          9   10




              CLIENT ONE                                CLIENT TWO



                                                              @robrighter
Setup the Updater
fu.get("/update", function (req, res) {
       //Send the HTTP Headers
      res.sendHeader(200,{"Content-Type": "text/html"});
      
       //Parse out the since from the query string
       var thesince;
      if(url.parse(req.url,true).hasOwnProperty('query') &&
url.parse(req.url,true).query.hasOwnProperty('since')){
          thesince = parseInt(url.parse(req.url,true)['query']['since']);
      }
      else {
          thesince = -1;
      }

      //Setup the datalistener (note why this works so well with JS scoping)
      rb.addListenerForUpdateSince(thesince, function(data){
           var body = '['+_.map(data,JSON.stringify).join(',n')+']';
           res.write( body );
           res.close();
      });
});



                                                                    @robrighter
Client Side




              @robrighter
Long Polling Request
var url = “/update?since=” + lastrecieved;
$.getJSON(url, function(data){

 
 
       var itemstoadd = _.map(data.reverse(),function(item){

 
 
 
        lastrecieved = item["offset"];

 
 
 
        return domainmarkup(item['value']);

 
 
 
      });
 

 
 
 
      var uc = $("#updatedcontent");

 
 
 
      _.map(itemstoadd, function(item){

 
 
 
        if(!interrupt){

 
 
 
            uc.prepend(item);

 
 
 
        }

 
 
 
      });

 
 
 
             setTimeout('getupdate(lastrecieved)', 1000);
});




                                                   @robrighter
Questions?


github.com/robrighter

twitter.com/robrighter




                 @robrighter

robrighter's Node.js presentation for DevChatt

  • 1.
    Current @robrighter
  • 2.
    What is Node.js? _non-blocking _ evented _ javascript @robrighter
  • 3.
    Why is nodeuseful? @robrighter
  • 4.
    Why is nodeuseful? It can handle a ton of concurrent connections @robrighter
  • 5.
    A Gross Oversimplification of HTTP Give me a page Sure Connection Closed @robrighter
  • 6.
    AJAX Polling Got any updates? No Connection Closed Got any updates? No Connection Closed @robrighter
  • 7.
    Comet Got any updates? ...wait Yes Connection Closed @robrighter
  • 8.
    Websocket asyncronous updates @robrighter
  • 9.
  • 10.
  • 11.
    Evented Example fs.readFile("./file", function(err, data) { if (err) throw err; sys.puts(data); }); @robrighter
  • 12.
    An Example @robrighter
  • 13.
    Server Side @robrighter
  • 14.
    Setup the DataSource var rb = new lpb.LongPollingBuffer(70); var dump = process.createChildProcess("tcpdump",["-i","en1","-A","-n","port", "80"]); var ignorelist = ['localhost','foxnews.com']; //Setup the listener to handle the flow of data from the dump dump.addListener("output", function (data) {     var hosts = data.match(/Host: (.*)/g);     if(hosts){         _.each(hosts, function(item){             var out = item.slice(6);             sys.puts(out);             if(!_.detect(ignorelist, function(s){ return (item.indexOf(s) > -1); })){                 rb.push(out);             }                      });     } }); @robrighter
  • 15.
    LongPollingBuffer DATA ARRAY DATA: 1 1 1 0 1 0 0 1 1 0 OFFSET: 0 2 3 4 5 6 7 8 9 10 CLIENT ONE CLIENT TWO @robrighter
  • 16.
    Setup the Updater fu.get("/update",function (req, res) { //Send the HTTP Headers       res.sendHeader(200,{"Content-Type": "text/html"});        //Parse out the since from the query string var thesince;       if(url.parse(req.url,true).hasOwnProperty('query') && url.parse(req.url,true).query.hasOwnProperty('since')){           thesince = parseInt(url.parse(req.url,true)['query']['since']);       }       else {           thesince = -1;       } //Setup the datalistener (note why this works so well with JS scoping)       rb.addListenerForUpdateSince(thesince, function(data){            var body = '['+_.map(data,JSON.stringify).join(',n')+']';            res.write( body );            res.close();       }); }); @robrighter
  • 17.
    Client Side @robrighter
  • 18.
    Long Polling Request varurl = “/update?since=” + lastrecieved; $.getJSON(url, function(data){ var itemstoadd = _.map(data.reverse(),function(item){ lastrecieved = item["offset"]; return domainmarkup(item['value']); });   var uc = $("#updatedcontent"); _.map(itemstoadd, function(item){ if(!interrupt){ uc.prepend(item); } }); setTimeout('getupdate(lastrecieved)', 1000); }); @robrighter
  • 19.