SlideShare a Scribd company logo
Node.JS
Stefan Matthias Aust
JavaScript
JavaScript
ECMAScript
V8

• JavaScript-Engine von Google
• Opensource-Projekt (C++)
• ECMAScript 3-kompatibel
• Verdammt schnell (JIT-Compiler)
Empfehlung




http://www.slideshare.net/simon/a-reintroduction-to-javascript
Empfehlung



Douglas Crockford "JavaScript: The Good Parts"
Argumente

• klein & einfach
• dynamisch
• objektorientiert
• allgegenwärtig
Node.JS
Argumente

• klein & leichtgewichtig
• gleiche Sprache wie im Browser
• asynchrones I/O
• HTTP-Client und -Server
• keine Threads
Installation
# download
$ git clone git://github.com/ry/node.git

#   compile
$   cd node
$   ./configure
$   make

# run
$ ./node hello.js

# read doc
$ man doc/node.1
Hallo Welt (Konsole)


// import module
var sys = require("sys");

// greet the world
sys.puts("Hallo, Welt");




                            12
Hallo Welt (Server)

// import module
var http = require("http");

// create an HTTP server on port 8000
http.createServer(function(req, res) {
  res.sendHeader(200, {"content-type": "text/plain"});
  res.sendBody("Hallo, Welt");
  res.finish();
}).listen(8000);




                              13
Promises
// import module
var sys = require("sys");
var posix = require("posix");

// load a file
var promise = posix.open("file.txt", posix.O_RDONLY);
promise.addCallback(function(fd) {
  var promise = posix.read(fd, 1024, 0, "utf-8");
  promise.addCallback(function(data) {
    sys.puts(data);
    posix.close(fd);
  });
});

// shortcut
var data = posix.cat("file.txt").wait();



                           14
Echo-Server
var tcp = require("tcp");

var server = tcp.createServer(function (socket) {
  socket.setEncoding("utf8");
  socket.addListener("connect", function () {
    socket.send("hellorn");
  });
  socket.addListener("receive", function (data) {
    socket.send(data);
  });
  socket.addListener("eof", function () {
    socket.send("goodbyern");
    socket.close();
  });
});
server.listen(7000);
Chat-Example
Server mit URL-Dispatcher
// fu.js
var server = createServer(function(req, res) {
  if (req.method == "GET") {
    (getPaths[req.uri.path] || notFound)(req, res);
  }
});

function notFound(req, res) {
  res.sendHeader(404, { "content-type": "text/plain" });
  res.sendBody("Not Found"); res.finish();
}

exports.listen = function(port) {
   server.listen(port || 8080);
};

exports.close = server.close;



                           17
Handler registrieren
// fu.js
var getPaths = {};

exports.get = function(path, handler) {
   getPaths[path] = handler;
};




// chat.js
var fu = require("fu");
fu.get("/", function(req, res) { ... });
fu.get("/style.css", fu.staticHandler("style.css"));
fu.listen();




                           18
Beispiel-Handler
// fu.js
exports.staticHandler = function(filename) {
   var contentType = _contentType(filename);
   var encoding = _encoding(contentType);
   return function(req, res) {
      var promise = posix.cat(filename, encoding);
      promise.addCallback(function(data) {
        res.sendHeader(200, {
          "content-type": contentType,
          "content-length": data.length
        });
        res.sendBody(data);
        res.finish();
      });
   };
};



                            19
join & part
// chat.js
fu.get("/join", function(req, res) {
  var nick = req.uri.params["nick"];
  var session = createSession(nick);
  channel.addMessage("join", nick, "");
  res.json(200, {id: session.id, nick: nick});
});

fu.get("/part", function(req, res) {
  var session = sessions[req.uri.params["id"]];
  session.destroy();
  res.json(200, {});
}




                           20
create sessions
// chat.js
var sessions = {};

function createSession(nick) {
  var session = {
     id: Math.floor(Math.random() * 99999999999),
     nick: nick,
     timestamp: new Date(),
     destroy: function() {
       channel.addMessage("part", this.nick);
       delete sessions[this.id];
     }
  };
  return sessions[session.id] = session;
}




                            21
get users & send message
// chat.js
fu.get("/who", function(req, res) {
  var nicks = _.map(sessions, function(s) {
    return s.nick;
  });
  res.json(200, {nicks: nicks});
});

fu.get("/send", function(req, res) {
  var session = sessions[req.uri.params.id];
  channel.addMessage("msg",
    session.nick,
    req.uri.params.text);
  res.json(200, {});
});




                           22
add & dispatch message
// chat.js
var channel = {
  messages: [],
  callbacks: [],

  addMessage: function(cmd, nick, text) {
    var m = {cmd: cmd, nick: nick, text: text};
    this.messages.push(m);
    for (var i in callbacks) {
      this.callbacks[i](m);
    }
  }
  ...
};




                           23
get old messages

// chat.js
fu.get("/get", function(req, res) {
  var session = sessions[req.uri.params.id];
  var since = parseInt(req.uri.params.since, 10);
  channel.query(since, function(messages) {
    res.json(200, {messages: messages});
  });
});




                           24
get msg & register interest
// chat.js
var channel = {
   ...,
   query: function(since, callback) {
     var matching = [];
     for (var i in messages) {
        if messages[i].timestamp > since)
          matching.push(messages[i]);
     }
     if (matching.length > 0) {
        callback(matching);
     } else {
        callbacks.push(callback);
     }
   }
};



                             25
cleanup


setInterval(function () {
  var now = new Date();
  while (callbacks.length > 0 &&
          now - callbacks[0].timestamp > 30*1000) {
    callbacks.shift().callback([]);
  }
}, 1000);

More Related Content

What's hot (20)

DOC
Correcion
diegorap
 
PDF
Тененёв Анатолий, Boost.Asio в алгоритмической торговле
Platonov Sergey
 
PDF
Progressive Mobile Web Apps
dynamis
 
PDF
Rambler.iOS #8: Чистые unit-тесты
RAMBLER&Co
 
DOCX
Rafael torrest
rfltorres
 
TXT
Lab 10 rus razvan
Razvan Rus
 
TXT
Dispositivos 4B
Richard Astudillo
 
PDF
Sockets java
Giovani Hernandez
 
TXT
Hello world
Nagarajan S
 
KEY
How to stop writing spaghetti code - JSConf.eu 2010
Tom Croucher
 
PDF
Java AWT Calculadora
jubacalo
 
PDF
商派信息安全解决方案
wanglei999
 
PPTX
The Flavor of TypeScript
Dmitry Sheiko
 
PDF
Java Thread Cronometro
jubacalo
 
TXT
Some logics
santwana 3
 
PPTX
JavaScript Assíncrono
Natã Barbosa
 
DOCX
Tugas pemrograman jaringan
Banser Sahara
 
PDF
Invoke y como poner en marcha un entorno de trabajo
NaN-tic
 
DOCX
Dasar c
Alvin Setiawan
 
PDF
PyconRu 2016. Осторожно, DSL!
Ivan Tsyganov
 
Correcion
diegorap
 
Тененёв Анатолий, Boost.Asio в алгоритмической торговле
Platonov Sergey
 
Progressive Mobile Web Apps
dynamis
 
Rambler.iOS #8: Чистые unit-тесты
RAMBLER&Co
 
Rafael torrest
rfltorres
 
Lab 10 rus razvan
Razvan Rus
 
Dispositivos 4B
Richard Astudillo
 
Sockets java
Giovani Hernandez
 
Hello world
Nagarajan S
 
How to stop writing spaghetti code - JSConf.eu 2010
Tom Croucher
 
Java AWT Calculadora
jubacalo
 
商派信息安全解决方案
wanglei999
 
The Flavor of TypeScript
Dmitry Sheiko
 
Java Thread Cronometro
jubacalo
 
Some logics
santwana 3
 
JavaScript Assíncrono
Natã Barbosa
 
Tugas pemrograman jaringan
Banser Sahara
 
Invoke y como poner en marcha un entorno de trabajo
NaN-tic
 
PyconRu 2016. Осторожно, DSL!
Ivan Tsyganov
 

Viewers also liked (8)

PPT
Car LEDs
digfun
 
ODP
Actp10
battlefield
 
KEY
Well... It's Japan / まあね... 日本だから。
Paul Sebastian Ziegler
 
PPT
15 Min Car Wash
digfun
 
PDF
Rs Portfolio 09 2010
rodneysh
 
PPTX
Lastname Firstname Lesson1 Yourperiod
elizabeth1997
 
PPT
REGGAETON ....
karen
 
ODP
Actp10
battlefield
 
Car LEDs
digfun
 
Actp10
battlefield
 
Well... It's Japan / まあね... 日本だから。
Paul Sebastian Ziegler
 
15 Min Car Wash
digfun
 
Rs Portfolio 09 2010
rodneysh
 
Lastname Firstname Lesson1 Yourperiod
elizabeth1997
 
REGGAETON ....
karen
 
Actp10
battlefield
 
Ad

Node.JS

  • 5. V8 • JavaScript-Engine von Google • Opensource-Projekt (C++) • ECMAScript 3-kompatibel • Verdammt schnell (JIT-Compiler)
  • 8. Argumente • klein & einfach • dynamisch • objektorientiert • allgegenwärtig
  • 10. Argumente • klein & leichtgewichtig • gleiche Sprache wie im Browser • asynchrones I/O • HTTP-Client und -Server • keine Threads
  • 11. Installation # download $ git clone git://github.com/ry/node.git # compile $ cd node $ ./configure $ make # run $ ./node hello.js # read doc $ man doc/node.1
  • 12. Hallo Welt (Konsole) // import module var sys = require("sys"); // greet the world sys.puts("Hallo, Welt"); 12
  • 13. Hallo Welt (Server) // import module var http = require("http"); // create an HTTP server on port 8000 http.createServer(function(req, res) { res.sendHeader(200, {"content-type": "text/plain"}); res.sendBody("Hallo, Welt"); res.finish(); }).listen(8000); 13
  • 14. Promises // import module var sys = require("sys"); var posix = require("posix"); // load a file var promise = posix.open("file.txt", posix.O_RDONLY); promise.addCallback(function(fd) { var promise = posix.read(fd, 1024, 0, "utf-8"); promise.addCallback(function(data) { sys.puts(data); posix.close(fd); }); }); // shortcut var data = posix.cat("file.txt").wait(); 14
  • 15. Echo-Server var tcp = require("tcp"); var server = tcp.createServer(function (socket) { socket.setEncoding("utf8"); socket.addListener("connect", function () { socket.send("hellorn"); }); socket.addListener("receive", function (data) { socket.send(data); }); socket.addListener("eof", function () { socket.send("goodbyern"); socket.close(); }); }); server.listen(7000);
  • 17. Server mit URL-Dispatcher // fu.js var server = createServer(function(req, res) { if (req.method == "GET") { (getPaths[req.uri.path] || notFound)(req, res); } }); function notFound(req, res) { res.sendHeader(404, { "content-type": "text/plain" }); res.sendBody("Not Found"); res.finish(); } exports.listen = function(port) { server.listen(port || 8080); }; exports.close = server.close; 17
  • 18. Handler registrieren // fu.js var getPaths = {}; exports.get = function(path, handler) { getPaths[path] = handler; }; // chat.js var fu = require("fu"); fu.get("/", function(req, res) { ... }); fu.get("/style.css", fu.staticHandler("style.css")); fu.listen(); 18
  • 19. Beispiel-Handler // fu.js exports.staticHandler = function(filename) { var contentType = _contentType(filename); var encoding = _encoding(contentType); return function(req, res) { var promise = posix.cat(filename, encoding); promise.addCallback(function(data) { res.sendHeader(200, { "content-type": contentType, "content-length": data.length }); res.sendBody(data); res.finish(); }); }; }; 19
  • 20. join & part // chat.js fu.get("/join", function(req, res) { var nick = req.uri.params["nick"]; var session = createSession(nick); channel.addMessage("join", nick, ""); res.json(200, {id: session.id, nick: nick}); }); fu.get("/part", function(req, res) { var session = sessions[req.uri.params["id"]]; session.destroy(); res.json(200, {}); } 20
  • 21. create sessions // chat.js var sessions = {}; function createSession(nick) { var session = { id: Math.floor(Math.random() * 99999999999), nick: nick, timestamp: new Date(), destroy: function() { channel.addMessage("part", this.nick); delete sessions[this.id]; } }; return sessions[session.id] = session; } 21
  • 22. get users & send message // chat.js fu.get("/who", function(req, res) { var nicks = _.map(sessions, function(s) { return s.nick; }); res.json(200, {nicks: nicks}); }); fu.get("/send", function(req, res) { var session = sessions[req.uri.params.id]; channel.addMessage("msg", session.nick, req.uri.params.text); res.json(200, {}); }); 22
  • 23. add & dispatch message // chat.js var channel = { messages: [], callbacks: [], addMessage: function(cmd, nick, text) { var m = {cmd: cmd, nick: nick, text: text}; this.messages.push(m); for (var i in callbacks) { this.callbacks[i](m); } } ... }; 23
  • 24. get old messages // chat.js fu.get("/get", function(req, res) { var session = sessions[req.uri.params.id]; var since = parseInt(req.uri.params.since, 10); channel.query(since, function(messages) { res.json(200, {messages: messages}); }); }); 24
  • 25. get msg & register interest // chat.js var channel = { ..., query: function(since, callback) { var matching = []; for (var i in messages) { if messages[i].timestamp > since) matching.push(messages[i]); } if (matching.length > 0) { callback(matching); } else { callbacks.push(callback); } } }; 25
  • 26. cleanup setInterval(function () { var now = new Date(); while (callbacks.length > 0 && now - callbacks[0].timestamp > 30*1000) { callbacks.shift().callback([]); } }, 1000);