Node.js

An Overview

Heinrich Göbl

www.goebl.com

About me

  • Heinrich Göbl
  • IT-Freelancer (Architecture, Software-Development)
  • Focus on Java EE
  • “Node.js rocks!”

What is Node?


for

What is Node?


perfect for

And ...

Typical Uses

See also: http://nodeguide.com/convincing_the_boss.html

Other facts/infos:

REPL (Read-Eval-Print-Loop)


Demo!?

Hello World

console.log('Hello stdout-World');
var http = require('http'), handler, server;

handler = function (req, res) {
    res.writeHead(200);
    res.end('Hello http-World');
};
server = http.createServer(handler);
server.listen(7001); // Port is 7001

Modules

Definition (add.js)

function add(a, b) {
  return a + b;
}
exports.add = add;

Consumption (calc.js)

var add = require('./add.js').add;

console.log('4 + 5 =', add(4, 5));

Local/Module Scope

Classic JavaScript

(function (global) {
    var someLocalData = {};
    function privateHelper() {}
    global.tool = function () {
        // use privateHelper
        // access someLocalData
    };
}(window));


Or use a Module Loader (AMD, ...)

Local/Module Scope

The Node Way

var someLocalData = {};

function privateHelper() {}

function mytool() {
    // use privateHelper
    // access someLocalData
}

exports.tool = mytool;

Synchronous vs. Asynchronous

// synchronous (waiting ...)
var result = db.query("select * from tab");
// after some time:
result.forEach(/* use result */);


// asynchronous
db.query("select * from tab", function (result) {
    result.forEach(/* use result */);
});
// proceeding w/o waiting

Async Style Advantages

Global Objects

Core Modules

Example: net

var net = require('net');

net.createServer(function (stream) {
    stream.write('hello\r\n');
    stream.on('end', function () {
        stream.end('goodbye\r\n');
    });
    stream.pipe(stream);
}).listen(7000);

Asynchronous Programming Style

Callbacks


Event Emitters

Event Emitter Example

function LineInfoEmitter(options, rules) {
    var self = this; // ...
    function processData(data) { //  ...
        self.emit('lineInfo', lineInfo);
    }
    stdin.on('data', processData);
    stdin.on('end', function () {
        if (incompleteLine) {processData('\n');}
        self.emit('end');
    });
}
util.inherits(LineInfoEmitter, EventEmitter);
Full source see github.com/hgoebl/entintar

Event Consumer

logstream = fs.createWriteStream(logfile, {flags:'w'});
logstream.on('open', function () {});
logstream.on('error', function (err) {});

lineInfoEmitter.on('lineInfo', function (lineInfo) {
    logstream.write(lineInfo.line + '\n', encoding);
});

lineInfoEmitter.on('end', function () {
    logstream.on('drain', function () {
        logstream.end();
    });
});
Full source see github.com/hgoebl/entintar

Callback Example

function getSomeData(input, callback) {
  db.asyncSelect(input, function(error, result) {
    if (error) {
      callback(error);
      return;
    }
    // transform result, e.g. map/reduce
    callback(null, result);
  });
}

Fight the X-mas Tree

client.useDatabase('mydb', function (err) {
  if (err) { ... }
  client.query("SELECT * FROM usr",
    function (err, results, fields) {
      if (err) { ... }
      results.forEach(function (row) {
        console.log(item);
      });
      client.end(function (err) {
        if (err) { ... }
        console.log('done');
      });
    });
});

async

async.series([
    function(){ ... },
    function(){ ... }
]);

seq

Seq()
  .seq(function ()    { ...; this(null,arg)})
  .par(function (arg) { ...; this(null,a1})
  .par(function (arg) { ...; this(null,a2})
  .seq(function (a1, a2) {   });


Demo/Examples?

npm

package.json

{ "name": "marked",
  "description": "A markdown parser built for speed",
  "author": "Christopher Jeffrey",
  "version": "0.1.6",
  "main": "./lib/marked.js",
  "bin": { "marked": "./bin/marked" },
  "repository": "git://github.com/chjj/marked.git",
  "keywords": [ "markdown", "markup", "html" ]
}

Example shortened

Use npm

$ npm install mysql
$ npm install -g mocha

$ npm update
$ npm list

$ npm test
$ npm publish
npm config set browser chromium-browser
npm docs mocha
npm help
npm help npm
npm list | ls
npm test
npm up | update
npm start
  -> defaults to node server.js

npm registry

Community Modules


Example: jsdom

var jsdom = require("jsdom");
jsdom.env("http://localhost:8008/javascript/",
    [ 'http://code.jquery.com/jquery-1.7.1.js' ],
    function (error, window) {
        if (error) { throw error; }
        window.$('div.slide').
                find('h1:first').
                each(function (index) {
            console.log(index, window.$(this).text());
        });
    });

Connect

Connect is a middleware framework for node, shipping with over 18 bundled middleware and a rich selection of 3rd-party middleware.“

var app = connect()
  .use(connect.logger('dev'))
  .use(connect.static('public'))
  .use(function(req, res){
    res.end('hello world\n');
  })
 .listen(3000);

Connect Middleware

express

express Example

GET /books

app.get('/books/:bookId([a-f0-9]{24})',
  function (req, res) {
    bookStore.findById(req.params.bookId,
      function (error, book) {
        if (error) {
          res.send({ success:false, error:error});
        } else if (book === null) {
          res.send(404);
        } else {
          res.send({ success:true, data:book});
        }
      });
  });

jade - node template engine

doctype 5
html(lang="en")
  head
    title= pageTitle
  body
    h1 Jade
    #container
      if youAreUsingJade
        p You are amazing
      else
        p Get on it!
<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Jade</title>
  </head>
  <body>
    <h1>Jade</h1>
    <div id="container">
      <p>You are amazing</p>
    </div>
  </body>
</html>

Socket.IO

WebSocket Request

GET ws://localhost:8008/socket.io/1/websocket/ ↵
   →   16691598151823705646 HTTP/1.1
Origin: http://localhost:8008
Connection: Upgrade
Host: localhost:8008
Sec-WebSocket-Key: 5qE8eKPepP/xWhWnr2Mjqg==
Upgrade: websocket
Sec-WebSocket-Version: 13

WebSocket Response

HTTP/1.1 101 Switching Protocols
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Accept: RDaVahzV8dztrUzeJ9WXC5NesG8=

IO - Server

var io = require('socket.io').listen(8118);

io.sockets.on('connection', function (socket) {
  socket.on('new-message', function (data) {
    console.log('arrived:', data, 'from:', socket.id);
    socket.broadcast.emit('new-message', data);
  });
});

simplified - see code-snippets/nodejs/socket-io-server.js

IO - Client

<script src="/socket.io/socket.io.js"></script>
<script>
  var socket = io.connect();
  socket.on('new-message', function (data) {
    console.log('message arrived', data);
    $('#messages').append($('<li>').text(data));
  });
  $('#send').click(function () {
    socket.emit('new-message', $('#msg').val());
  });
</script>

simplified - see code-snippets/nodejs/socket-io-client.html

http://psitsmike.com/2011/09/node-js-and-socket-io-chat-tutorial/ http://www.zachstronaut.com/posts/2011/08/17/node-socket-io-curious.html http://www.catonmat.net/blog/nodejs-modules-socketio/

Testing


Additional (Node only)

Debugging


Demo?

Node Hosting

Conclusion

Pro

Contra

Reading

Internet


Books

Questions?

Thank you!

// my mail address
'hgoebl+goebl.com'.replace('+', '@')

Backup

image/svg+xml
taken from: http://rationalwiki.org/ (Creative Commons Licensed)