SlideShare uma empresa Scribd logo
1 de 26
Baixar para ler offline
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);

Mais conteúdo relacionado

Mais procurados

Тененёв Анатолий, Boost.Asio в алгоритмической торговле
Тененёв Анатолий, Boost.Asio в алгоритмической торговлеТененёв Анатолий, Boost.Asio в алгоритмической торговле
Тененёв Анатолий, Boost.Asio в алгоритмической торговлеPlatonov Sergey
 
Progressive Mobile Web Apps
Progressive Mobile Web AppsProgressive Mobile Web Apps
Progressive Mobile Web Appsdynamis
 
Rambler.iOS #8: Чистые unit-тесты
Rambler.iOS #8: Чистые unit-тестыRambler.iOS #8: Чистые unit-тесты
Rambler.iOS #8: Чистые unit-тестыRAMBLER&Co
 
Rafael torrest
Rafael torrestRafael torrest
Rafael torrestrfltorres
 
Lab 10 rus razvan
Lab 10   rus razvanLab 10   rus razvan
Lab 10 rus razvanRazvan Rus
 
How to stop writing spaghetti code - JSConf.eu 2010
How to stop writing spaghetti code - JSConf.eu 2010How to stop writing spaghetti code - JSConf.eu 2010
How to stop writing spaghetti code - JSConf.eu 2010Tom Croucher
 
Java AWT Calculadora
Java AWT CalculadoraJava AWT Calculadora
Java AWT Calculadorajubacalo
 
商派信息安全解决方案
商派信息安全解决方案商派信息安全解决方案
商派信息安全解决方案wanglei999
 
The Flavor of TypeScript
The Flavor of TypeScriptThe Flavor of TypeScript
The Flavor of TypeScriptDmitry Sheiko
 
Java Thread Cronometro
Java Thread CronometroJava Thread Cronometro
Java Thread Cronometrojubacalo
 
JavaScript Assíncrono
JavaScript AssíncronoJavaScript Assíncrono
JavaScript AssíncronoNatã Barbosa
 
Tugas pemrograman jaringan
Tugas pemrograman jaringanTugas pemrograman jaringan
Tugas pemrograman jaringanBanser Sahara
 
Invoke y como poner en marcha un entorno de trabajo
Invoke y como poner en marcha un entorno de trabajoInvoke y como poner en marcha un entorno de trabajo
Invoke y como poner en marcha un entorno de trabajoNaN-tic
 
PyconRu 2016. Осторожно, DSL!
PyconRu 2016. Осторожно, DSL!PyconRu 2016. Осторожно, DSL!
PyconRu 2016. Осторожно, DSL!Ivan Tsyganov
 

Mais procurados (20)

Correcion
CorrecionCorrecion
Correcion
 
Тененёв Анатолий, Boost.Asio в алгоритмической торговле
Тененёв Анатолий, Boost.Asio в алгоритмической торговлеТененёв Анатолий, Boost.Asio в алгоритмической торговле
Тененёв Анатолий, Boost.Asio в алгоритмической торговле
 
Progressive Mobile Web Apps
Progressive Mobile Web AppsProgressive Mobile Web Apps
Progressive Mobile Web Apps
 
Rambler.iOS #8: Чистые unit-тесты
Rambler.iOS #8: Чистые unit-тестыRambler.iOS #8: Чистые unit-тесты
Rambler.iOS #8: Чистые unit-тесты
 
Rafael torrest
Rafael torrestRafael torrest
Rafael torrest
 
Lab 10 rus razvan
Lab 10   rus razvanLab 10   rus razvan
Lab 10 rus razvan
 
Dispositivos 4B
Dispositivos 4BDispositivos 4B
Dispositivos 4B
 
Sockets java
Sockets javaSockets java
Sockets java
 
Hello world
Hello worldHello world
Hello world
 
How to stop writing spaghetti code - JSConf.eu 2010
How to stop writing spaghetti code - JSConf.eu 2010How to stop writing spaghetti code - JSConf.eu 2010
How to stop writing spaghetti code - JSConf.eu 2010
 
Java AWT Calculadora
Java AWT CalculadoraJava AWT Calculadora
Java AWT Calculadora
 
商派信息安全解决方案
商派信息安全解决方案商派信息安全解决方案
商派信息安全解决方案
 
The Flavor of TypeScript
The Flavor of TypeScriptThe Flavor of TypeScript
The Flavor of TypeScript
 
Java Thread Cronometro
Java Thread CronometroJava Thread Cronometro
Java Thread Cronometro
 
Some logics
Some logicsSome logics
Some logics
 
JavaScript Assíncrono
JavaScript AssíncronoJavaScript Assíncrono
JavaScript Assíncrono
 
Tugas pemrograman jaringan
Tugas pemrograman jaringanTugas pemrograman jaringan
Tugas pemrograman jaringan
 
Invoke y como poner en marcha un entorno de trabajo
Invoke y como poner en marcha un entorno de trabajoInvoke y como poner en marcha un entorno de trabajo
Invoke y como poner en marcha un entorno de trabajo
 
Dasar c
Dasar cDasar c
Dasar c
 
PyconRu 2016. Осторожно, DSL!
PyconRu 2016. Осторожно, DSL!PyconRu 2016. Осторожно, DSL!
PyconRu 2016. Осторожно, DSL!
 

Destaque

Car LEDs
Car LEDsCar LEDs
Car LEDsdigfun
 
Well... It's Japan / まあね... 日本だから。
Well... It's Japan / まあね... 日本だから。Well... It's Japan / まあね... 日本だから。
Well... It's Japan / まあね... 日本だから。Paul Sebastian Ziegler
 
15 Min Car Wash
15 Min Car Wash15 Min Car Wash
15 Min Car Washdigfun
 
Rs Portfolio 09 2010
Rs Portfolio 09 2010Rs Portfolio 09 2010
Rs Portfolio 09 2010rodneysh
 
Lastname Firstname Lesson1 Yourperiod
Lastname Firstname Lesson1 YourperiodLastname Firstname Lesson1 Yourperiod
Lastname Firstname Lesson1 Yourperiodelizabeth1997
 
REGGAETON ....
REGGAETON ....REGGAETON ....
REGGAETON ....karen
 

Destaque (8)

Car LEDs
Car LEDsCar LEDs
Car LEDs
 
Actp10
Actp10Actp10
Actp10
 
Well... It's Japan / まあね... 日本だから。
Well... It's Japan / まあね... 日本だから。Well... It's Japan / まあね... 日本だから。
Well... It's Japan / まあね... 日本だから。
 
15 Min Car Wash
15 Min Car Wash15 Min Car Wash
15 Min Car Wash
 
Rs Portfolio 09 2010
Rs Portfolio 09 2010Rs Portfolio 09 2010
Rs Portfolio 09 2010
 
Lastname Firstname Lesson1 Yourperiod
Lastname Firstname Lesson1 YourperiodLastname Firstname Lesson1 Yourperiod
Lastname Firstname Lesson1 Yourperiod
 
REGGAETON ....
REGGAETON ....REGGAETON ....
REGGAETON ....
 
Actp10
Actp10Actp10
Actp10
 

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);