Einführung in Node.js

154
Monday, March 11, 13

description

JavaScript Days 2013

Transcript of Einführung in Node.js

Page 1: Einführung in Node.js

Monday, March 11, 13

Page 2: Einführung in Node.js

WER BIN ICH?

• Sebastian Springer

• https://github.com/sspringer82

• @basti_springer

• Teamlead @ Mayflower

Monday, March 11, 13

Page 3: Einführung in Node.js

THEMEN• Installation

• Node.js Shell

• Kernkomponenten

• NPM

• Events

• Streams

• HTTP

• Dateisystem

• Debugger

• Child_Process

• Cluster

• Tests

• Promises

Monday, March 11, 13

Page 5: Einführung in Node.js

INSTALLATION

Monday, March 11, 13

Page 7: Einführung in Node.js

INSTALLATION

Monday, March 11, 13

Page 8: Einführung in Node.js

INSTALLATIONAuf welchen Systemen ist Node.js verfügbar?

Monday, March 11, 13

Page 9: Einführung in Node.js

INSTALLATION• Unix

• /usr/local/bin/node

• /usr/local/bin/npm

• /usr/local/lib/node_modules

• Windows

• C:\Program Files\nodejs\node.exe

• C:\Program Files\nodejs\npm

• C:\Program Files\nodejs\node_modules

Monday, March 11, 13

Page 10: Einführung in Node.js

INSTALLATION

$ wget http://nodejs.org/dist/v0.8.21/node-v0.8.21.tar.gz...$ tar xvzf node-v0.8.21.tar.gz...$ cd node-v0.8.21/$ ./configure --prefix=/opt/node/node-v0.8.21...$ make...$ sudo make install...

Suchpfad anpassen!

Monday, March 11, 13

Page 11: Einführung in Node.js

INSTALLATION

$ node --versionv0.8.22

Hat es funktioniert?

Monday, March 11, 13

Page 12: Einführung in Node.js

REPL

Monday, March 11, 13

Page 13: Einführung in Node.js

WHAT?

Monday, March 11, 13

Page 14: Einführung in Node.js

READ-EVAL-PRINT-LOOP

DIE NODE.JS SHELL

Monday, March 11, 13

Page 15: Einführung in Node.js

REPL

$ node> for (var i = 0; i < 3; i++) {... console.log(i);... }012undefined>

Monday, March 11, 13

Page 16: Einführung in Node.js

REPL

.break Bricht ein Multiline Statement ab

.clear Zurücksetzen + .break (CTRL + C)

.exit Beendet die aktuelle Shell (CTRL + D)

.help Liste der Befehle

.save Speichert die aktuelle Session

.load Lädt eine gespeicherte Session

Monday, March 11, 13

Page 17: Einführung in Node.js

KERNKOMPONENTEN

Monday, March 11, 13

Page 18: Einführung in Node.js

KERNKOMPONENTENStandard Library

Node Bindings

V8 libuv

Eventloop async I/O

Monday, March 11, 13

Page 19: Einführung in Node.js

KERNKOMPONENTENStandard Library

Node Bindings

V8 libuv

Eventloop async I/O

Monday, March 11, 13

Page 20: Einführung in Node.js

KERNKOMPONENTEN

Monday, March 11, 13

Page 21: Einführung in Node.js

KERNKOMPONENTENStandard Library

Node Bindings

V8 libuv

Eventloop async I/O

Monday, March 11, 13

Page 22: Einführung in Node.js

KERNKOMPONENTENStandard Library

Node Bindings

V8 libuv

Eventloop async I/O

Monday, March 11, 13

Page 23: Einführung in Node.js

V8

• Schneller Zugriff auf Eigenschaften

• Dynamische Erstellung von Maschinencode

• Garbage Collection

Monday, March 11, 13

Page 24: Einführung in Node.js

V8 - FAST PROPERTY ACCESS

Monday, March 11, 13

Page 25: Einführung in Node.js

V8 - FAST PROPERTY ACCESS

Monday, March 11, 13

Page 26: Einführung in Node.js

V8 - FAST PROPERTY ACCESS

Monday, March 11, 13

Page 27: Einführung in Node.js

MASCHINENCODE

Monday, March 11, 13

Page 28: Einführung in Node.js

V8 - GARBAGE COLLECTION

• Programmausführung wird angehalten

• Es wird nur ein Teil des Object Heaps geprüft

• V8 kennt alle Objekte und Pointer im Speicher

Monday, March 11, 13

Page 29: Einführung in Node.js

KERNKOMPONENTENStandard Library

Node Bindings

V8 libuv

Eventloop async I/O

libev + libeio IOCPMonday, March 11, 13

Page 30: Einführung in Node.js

ASYNCHRONE OPERATIONEN

node.js Betriebssystem

Operation(z.B. lesen)

Monday, March 11, 13

Page 31: Einführung in Node.js

APPLIKATIONEN IN NODE.JS

Monday, March 11, 13

Page 32: Einführung in Node.js

APPLIKATIONEN IN NODE.JS

$ node helloWorld.js

Monday, March 11, 13

Page 33: Einführung in Node.js

X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X X XX X X

Monday, March 11, 13

Page 34: Einführung in Node.js

APPLIKATIONEN IN NODE.JSvar Star = function () { this.name = 'X', this.height = 20, this.step = 2;};

Star.prototype.top = function() { ...};

Star.prototype.print = function () { console.log(this.top().join('\n')); console.log(this.middle()); console.log(this.bottom().join('\n'));}

...

var star = new Star();star.print();

Monday, March 11, 13

Page 35: Einführung in Node.js

DAS MODULSYSTEM

Monday, March 11, 13

Page 36: Einführung in Node.js

DAS MODULSYSTEM

NPM

eigene Module

interne Module

Monday, March 11, 13

Page 37: Einführung in Node.js

INTERNE MODULEAssertion Testing

BufferChild_Process

ClusterCrypto

DebuggerDNS

DomainEvent

File System

HTTPHTTPS

NetOsPath

ProcessQueryString

ReadlineREPL

Stream

String DecoderTimersTLS/SSL

TTYUDPURL

UtilitiesVMZLIB

Monday, March 11, 13

Page 38: Einführung in Node.js

INTERNE MODULESTABILITÄTSINDEX

Index Name Beispiel

0 Deprecated util.pump

1 Experimental Domain, Cluster

2 Unstable Readline, Stream

3 Stable HTTP, Query String

4 API Frozen OS, Events

5 Locked Util, Assert

Monday, March 11, 13

Page 39: Einführung in Node.js

VERWENDUNG INTERNER MODULE

var os = require('os');

console.log('Betriebssystem: ' + os.type() + ' ' + os.platform() + ' ' + os.release() + ' ' + os.arch());

intModule.js

Monday, March 11, 13

Page 40: Einführung in Node.js

INTERNE MODULE - GLOBALS

• console

• process

• require

• Buffer

• set/clear-Timeout/Interval

• __filename + __dirname

Monday, March 11, 13

Page 41: Einführung in Node.js

EIGENE MODULE

Monday, March 11, 13

Page 42: Einführung in Node.js

EIGENE MODULE

• OH: “Wenn ich mir das Zeug, das in Node programmiert wurde, so ansehe, sieht das aus wie PHP3. Einfach von oben nach unten, alles in einer Datei”

• Liegen in einer separaten Datei

• Exportieren Klassen, Objekte oder Funktionen

• Können an anderer Stelle eingebunden werden

Monday, March 11, 13

Page 43: Einführung in Node.js

EIGENE MODULE

exports.email = function (email) { var regex = /^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/, result = regex.exec(email);

if (result) { return true; }

return false;};

validator.js

Monday, March 11, 13

Page 44: Einführung in Node.js

EIGENE MODULE

exports.email = function (email) { var regex = /^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/, result = regex.exec(email);

if (result) { return true; }

return false;};

validator.js

Monday, March 11, 13

Page 45: Einführung in Node.js

VERWENDUNG EIGENER MODULE

var validator = require('./validator.js'), mail = ['[email protected]', 'Invalid Address'];

for (var i = 0; i < mail.length; i++) { if (validator.email(mail[i])) { console.log((i + 1) + '. Mailadresse ist gültig'); } else { console.log((i + 1) + '. Mailadresse ist ungültig'); }}

modules.js

Monday, March 11, 13

Page 46: Einführung in Node.js

VERWENDUNG EIGENER MODULE

var validator = require('./validator.js'), mail = ['[email protected]', 'Invalid Address'];

for (var i = 0; i < mail.length; i++) { if (validator.email(mail[i])) { console.log((i + 1) + '. Mailadresse ist gültig'); } else { console.log((i + 1) + '. Mailadresse ist ungültig'); }}

modules.js

Monday, March 11, 13

Page 47: Einführung in Node.js

EIGENE MODULE

$ node modules.js1. Mailadresse ist gültig2. Mailadresse ist ungültig

Monday, March 11, 13

Page 48: Einführung in Node.js

Monday, March 11, 13

Page 49: Einführung in Node.js

NPM

• Node Package Manager (von Isaac Schlueter)

• Bestandteil von Node.js seit 0.6.3

• https://github.com/isaacs/npm

Monday, March 11, 13

Page 50: Einführung in Node.js

NPM - REPO

• Hier kommen die Pakete für das npm-Kommando her

• https://npmjs.org/

• Aktuell über 24.000 Pakete

• https://registry.npmjs.org/-/all/

Monday, March 11, 13

Page 51: Einführung in Node.js

KOMMANDOS

• npm search <package>

• npm install <package>

• npm list

• npm update

• npm remove

Monday, March 11, 13

Page 52: Einführung in Node.js

NPM SEARCH

$ npm se mysqlnpm http GET https://registry.npmjs.org/-/all/since?stale=update_aft...npm http 200 https://registry.npmjs.org/-/all/since?stale=update_aft...NAME DESCRIPTION AUTHOR DATE KEYWORDS...Accessor_M... A MySQL database wrapper... =bu 2012-1... mysql ac...any-db Database-agnostic connec... =grncdr 2013-0... mysql po...autodafe mvc framework for node w... =jifeon 2012-1... mvc fram...backbone-m... A sync module for Backbo... =ccowan 2012-1...caminte ORM for every database: ... =biggor 2013-0... caminte ...connect-my... a MySQL session store fo... =nathan 2012-0... connect-my... A MySQL session store fo... =daniel 2011-0...cormo ORM framework for Node.j... =croqui 2013-0... orm mong...

Monday, March 11, 13

Page 53: Einführung in Node.js

NPM INSTALL$ npm in mysqlnpm http GET https://registry.npmjs.org/mysqlnpm http 200 https://registry.npmjs.org/mysqlnpm http GET https://registry.npmjs.org/bignumber.js/1.0.1npm http GET https://registry.npmjs.org/require-all/0.0.3npm http 200 https://registry.npmjs.org/require-all/0.0.3npm http GET https://registry.npmjs.org/require-all/-/requi...npm http 200 https://registry.npmjs.org/bignumber.js/1.0.1npm http GET https://registry.npmjs.org/bignumber.js/-/bign...npm http 200 https://registry.npmjs.org/require-all/-/requi...npm http 200 https://registry.npmjs.org/bignumber.js/-/[email protected] node_modules/mysql!"" [email protected]#"" [email protected]

Monday, March 11, 13

Page 55: Einführung in Node.js

NPM UPDATE

$ npm upnpm http GET https://registry.npmjs.org/mysqlnpm http 304 https://registry.npmjs.org/mysqlnpm http GET https://registry.npmjs.org/require-all/0.0.3npm http GET https://registry.npmjs.org/bignumber.js/1.0.1npm http 304 https://registry.npmjs.org/bignumber.js/1.0.1npm http 304 https://registry.npmjs.org/require-all/0.0.3

Monday, March 11, 13

Page 56: Einführung in Node.js

NPM REMOVE

$ npm rm mysql$ npm ls/srv/node#"" (empty)

Monday, March 11, 13

Page 57: Einführung in Node.js

EIGENE NPM-PAKETE

Monday, March 11, 13

Page 58: Einführung in Node.js

{ "author": { "name": "Felix Geisendörfer", "email": "[email protected]", "url": "http://debuggable.com/" }, "name": "mysql", "description": "A node.js driver for mysql...", "version": "2.0.0-alpha7", "repository": { "url": "" }, "main": "./index", "scripts": { "test": "make test" }, "engines": { "node": "*" }, "dependencies": { "require-all": "0.0.3", "bignumber.js": "1.0.1" }, "devDependencies": { "utest": "0.0.6", "urun": "0.0.6", "underscore": "1.3.1" }, "optionalDependencies": {}, "readme": "# node-mysql\n\n[![Build Status]...", "readmeFilename": "Readme.md", "_id": "[email protected]", "_from": "mysql"}

Monday, March 11, 13

Page 59: Einführung in Node.js

EIGENE NPM-PAKETE

• npm adduser

• Username, Passwort, E-Mail

• npm publish <folder>|<tarball>

Monday, March 11, 13

Page 61: Einführung in Node.js

EVENTS

Monday, March 11, 13

Page 62: Einführung in Node.js

EVENTSEvent Emitter Subscriber

on(‘message’, function (e) {...

emit(‘message’, ‘data’)

Monday, March 11, 13

Page 63: Einführung in Node.js

EVENTS

• Basis vieler Module

• Grundlage für eventgetriebene Architektur

• Ereignisse zum Informationsaustausch

• emit(event, [arg1], [arg2], [...]) - Publish

• on(event, listener) - Subscribe

Monday, March 11, 13

Page 64: Einführung in Node.js

EVENTEMITTER

var EventEmitter = require('events').EventEmitter, util = require('util');

var MessageBus = function () {};

util.inherits(MessageBus, EventEmitter);

exports.MessageBus = MessageBus;

messageBus.js

Monday, March 11, 13

Page 65: Einführung in Node.js

EVENTEMITTER

var MessageBus = require('./messageBus.js').MessageBus;

var mb = new MessageBus();

mb.on('message', function (data) { console.log('Received new message: ' + data)});

mb.emit('message', 'Hello World');

events.js

Monday, March 11, 13

Page 66: Einführung in Node.js

EVENTEMITTER

$ node events.js Received new message: Hello World

Monday, March 11, 13

Page 67: Einführung in Node.js

EVENTS

• Wo kommen Events zum Einsatz?

• child_process, cluster, dgram, domain, fs, http, net, readline, repl, stream, tls

Monday, March 11, 13

Page 68: Einführung in Node.js

STREAMS

Monday, March 11, 13

Page 69: Einführung in Node.js

STREAMS

• Repräsentieren Datenströme in Node.js

• Abstraktes Interface

• Les- und/oder schreibbare Streams

Monday, March 11, 13

Page 70: Einführung in Node.js

READABLE STREAM

• Events

• data

• end

• error

• close

• Methoden

• pause

• resume

• destroy

• pipe

• setEncoding

Monday, March 11, 13

Page 71: Einführung in Node.js

WRITABLE STREAM

• Events

• drain

• error

• close

• pipe

• Methoden

• write

• end

• destroy

• destroySoon

Monday, March 11, 13

Page 72: Einführung in Node.js

STREAMS

• Wo kommen Streams zum Einsatz?

• fs, http, net repl, tls, zlib

Monday, March 11, 13

Page 73: Einführung in Node.js

STREAMS IN DER PRAXIS?

Monday, March 11, 13

Page 74: Einführung in Node.js

http://www.google.com

Monday, March 11, 13

Page 75: Einführung in Node.js

DER KLASSIKER

Monday, March 11, 13

Page 76: Einführung in Node.js

HTTP-SERVER

var http = require('http');

http.createServer(function (req, res) { res.end('Hello World');}).listen(8080);

http.js

Monday, March 11, 13

Page 77: Einführung in Node.js

HTTP-SERVER$ node http.js

Monday, March 11, 13

Page 78: Einführung in Node.js

require('http').createServer(function (req, res) { var body, status, reqData;

if (req.headers['user-agent'].search(/MSIE/) != -1) { body = 'wrong Browser'; status = 403; } else { body = 'Hello Client'; status = 200; }

req.on('data', function (data) { reqData += data; }).on('end', function () { if (reqData) console.log(reqData); });

res.writeHead(status, { 'Content-Length': body.length, 'Content-Type': 'text/plain' }); res.write(body); res.end();}).listen(8080);

Monday, March 11, 13

Page 79: Einführung in Node.js

HTTP-SERVER

• http.ServerRequest: Readable Stream

• http.ServerResponse: Writable Stream

Monday, March 11, 13

Page 80: Einführung in Node.js

HTTP-CLIENT?

Monday, March 11, 13

Page 81: Einführung in Node.js

var options = { hostname: 'www.google.de', port: 80, path: '/', method: 'get'};

var req = require('http').request(options, function(res) { console.log(res); res.setEncoding('utf8'); res.on('data', function (chunk) { console.log('BODY: ' + chunk); });});

req.on('error', function(e) { console.log('problem with request: ' + e.message);});

req.write('data\n');req.end();

Monday, March 11, 13

Page 82: Einführung in Node.js

var options = { hostname: 'www.google.de', port: 80, path: '/', method: 'get'};

var req = require('http').request(options, function(res) { console.log(res); res.setEncoding('utf8'); res.on('data', function (chunk) { console.log('BODY: ' + chunk); });});

req.write('data\n');req.end();

Monday, March 11, 13

Page 83: Einführung in Node.js

DATEISYSTEM

Monday, March 11, 13

Page 84: Einführung in Node.js

DATEISYSTEM-FUNKTIONEN

• exists

• readFile

• writeFile

• appendFile

• watchFile

• rename

• unlink

• chmod

• chown

• ...

Monday, March 11, 13

Page 85: Einführung in Node.js

SYNC VS. ASYNC

Monday, March 11, 13

Page 86: Einführung in Node.js

DATEI LESEN

var fs = require('fs') filename = process.argv[2] || 'input.txt';

fs.readFile(filename, 'utf8', function (err, data) { if (err) { console.error("File cound not be opened"); return false; } console.log(data); return true;});

Monday, March 11, 13

Page 87: Einführung in Node.js

DATEI LESEN

$ node readFile.jsHello World!

Monday, March 11, 13

Page 88: Einführung in Node.js

DATEI LESEN

$ node readFile.jsHello World!

$ node readFile.js nonexistant.txtFile cound not be opened

Monday, March 11, 13

Page 89: Einführung in Node.js

FILE EXISTS$ ls -l input.txt -rw-r--r-- 1 sspringer staff 12 Mar 7 09:06 input.txt

Monday, March 11, 13

Page 90: Einführung in Node.js

FILE EXISTS$ ls -l input.txt -rw-r--r-- 1 sspringer staff 12 Mar 7 09:06 input.txt

var fs = require('fs'), filename = process.argv[2] || 'input.txt';

fs.exists(filename, function (exists) { if (exists) { console.log('File exists'); return true; } console.error('There is no such file'); return false;});

Monday, March 11, 13

Page 91: Einführung in Node.js

FILE EXISTS$ ls -l input.txt -rw-r--r-- 1 sspringer staff 12 Mar 7 09:06 input.txt

var fs = require('fs'), filename = process.argv[2] || 'input.txt';

fs.exists(filename, function (exists) { if (exists) { console.log('File exists'); return true; } console.error('There is no such file'); return false;});

$ node fileExists.jsFile exists

Monday, March 11, 13

Page 92: Einführung in Node.js

APPEND FILE$ cat input.txtHello World!

Monday, March 11, 13

Page 93: Einführung in Node.js

APPEND FILE$ cat input.txtHello World!

var fs = require('fs'), data = process.argv[2] || 'Hello my World';

fs.appendFile('input.txt', data, function (err) { if (err) { console.error('Could not write into file'); return false; } console.log('Success!'); return true;});

Monday, March 11, 13

Page 94: Einführung in Node.js

APPEND FILE$ cat input.txtHello World!

var fs = require('fs'), data = process.argv[2] || 'Hello my World';

fs.appendFile('input.txt', data, function (err) { if (err) { console.error('Could not write into file'); return false; } console.log('Success!'); return true;});

$ node appendFile.js 'Hallo München!'Success!$ cat input.txt Hello World!Hallo München!

Monday, March 11, 13

Page 95: Einführung in Node.js

WATCH FILEvar fs = require('fs');

fs.watch('input.txt', function (e) { if (e === 'change') { console.log('File changed'); } else if (e === 'rename') { console.log('File renamed'); }});

Monday, March 11, 13

Page 96: Einführung in Node.js

WATCH FILE

$ node watchFile.js

var fs = require('fs');

fs.watch('input.txt', function (e) { if (e === 'change') { console.log('File changed'); } else if (e === 'rename') { console.log('File renamed'); }});

Monday, March 11, 13

Page 97: Einführung in Node.js

WATCH FILE

$ echo 'Hello World!' > input.txt

$ node watchFile.js

var fs = require('fs');

fs.watch('input.txt', function (e) { if (e === 'change') { console.log('File changed'); } else if (e === 'rename') { console.log('File renamed'); }});

Monday, March 11, 13

Page 98: Einführung in Node.js

WATCH FILE

$ echo 'Hello World!' > input.txt

$ node watchFile.js

$ node watchFile.js File changed

var fs = require('fs');

fs.watch('input.txt', function (e) { if (e === 'change') { console.log('File changed'); } else if (e === 'rename') { console.log('File renamed'); }});

Monday, March 11, 13

Page 99: Einführung in Node.js

DEBUGGER

Monday, March 11, 13

Page 100: Einführung in Node.js

BEISPIELCODEvar myObj = {a: 1, b: 2};

console.log(myObj);

myObj.a = 'Hello';

console.log(myObj);

for (var i = 0; i < 10; i++) { var helper = function () { // do something console.log(i) }; helper();}

Monday, March 11, 13

Page 101: Einführung in Node.js

DEBUGGER

$ node debug debugger.js< debugger listening on port 5858connecting... okbreak in debugger.js:1 1 var myObj = {a: 1, b: 2}; 2 3 console.log(myObj);debug>

Monday, March 11, 13

Page 102: Einführung in Node.js

DEBUGGER

$ node debug debugger.js< debugger listening on port 5858connecting... okbreak in debugger.js:1 1 var myObj = {a: 1, b: 2}; 2 3 console.log(myObj);debug>

Monday, March 11, 13

Page 103: Einführung in Node.js

DEBUGGER - STEP

Kommando Bedeutung Beschreibung

n next Fortsetzen

c cont Step over

s step Step in

o out Step out

Monday, March 11, 13

Page 104: Einführung in Node.js

DEBUGGER - WATCH

• watch(expression)

• unwatch(expression)

• watchers

Monday, March 11, 13

Page 105: Einführung in Node.js

DEBUGGER - WATCH

debug> watch('myObj')debug> nbreak in debugger.js:3Watchers: 0: myObj = {"b":2,"a":1}

1 var myObj = {a: 1, b: 2}; 2 3 console.log(myObj); 4 5 myObj.a = 'Hello';debug>

Monday, March 11, 13

Page 106: Einführung in Node.js

DEBUGGER - WATCH

debug> watch('myObj')debug> nbreak in debugger.js:3Watchers: 0: myObj = {"b":2,"a":1}

1 var myObj = {a: 1, b: 2}; 2 3 console.log(myObj); 4 5 myObj.a = 'Hello';debug>

Monday, March 11, 13

Page 107: Einführung in Node.js

DEBUGGER - REPLdebug> replPress Ctrl + C to leave debug repl> myObj{ b: 2, a: 1 }> myObj.b = 14;14> myObj{ b: 14, a: 1 }debug> n< { a: 1, b: 14 }break in debugger.js:5Watchers: 0: myObj = {"b":14,"a":1}

3 console.log(myObj); 4 5 myObj.a = 'Hello'; 6 7 console.log(myObj);debug>

Monday, March 11, 13

Page 108: Einführung in Node.js

DEBUGGER

• Kommandozeilen Debugger

• Kommandos

• Debugging einer Applikation

Monday, March 11, 13

Page 109: Einführung in Node.js

CHILD_PROCESS

Monday, March 11, 13

Page 110: Einführung in Node.js

CHILD_PROCESS

• spawn - Kommandoausführung

• exec - Kommandoausführung in Puffer

• execFile - Dateiausführung in Puffer

• fork - Node Prozess

Monday, March 11, 13

Page 111: Einführung in Node.js

ETWAS RECHENINTENSIVES

module.exports = function () { var i, n = 1, results = 1; primeLoop: while (results < 300000) { n += 1; for (i = 2; i <= Math.sqrt(n); i += 1) { if (n % i === 0) { continue primeLoop; } } results += 1; } return n;};

cp1.js

Monday, March 11, 13

Page 112: Einführung in Node.js

ETWAS BLOCKIERENDESpotenziell

var http = require('http');

http.createFakeServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World\n');}).listen(1337, '127.0.0.1');

console.log('Server running at http://127.0.0.1:1337/');

cp2.js

Monday, March 11, 13

Page 113: Einführung in Node.js

ETWAS BLOCKIERENDES

var http = require('http'), prime = require('./cp1.js');

http.createServer(function (req, res) { console.time('Request answered in'); console.log('incoming Request');

var number = prime();

res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('Hello World\n');

console.timeEnd('Request answered in');}).listen(1337, '127.0.0.1');

console.log('Server running at http://127.0.0.1:1337/');

cp3.js

Monday, March 11, 13

Page 114: Einführung in Node.js

ETWAS BLOCKIERENDES

$ node cp3.js Server running at http://127.0.0.1:1337/incoming RequestRequest answered in: 4713msincoming RequestRequest answered in: 4703ms

Monday, March 11, 13

Page 115: Einführung in Node.js

DIE LÖSUNG: WIR FORKEN

Monday, March 11, 13

Page 116: Einführung in Node.js

CHILD_PROCESS

var http = require('http');

http.createServer(function (req, res) { console.time('Request answered in'); console.log('incoming Request');

require('child_process').fork('./primeHelper.js') .on('message', function (data) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('The 300000st prime number is: ' + data.prime);

console.timeEnd('Request answered in'); });}).listen(1337, '127.0.0.1');

console.log('Server running at http://127.0.0.1:1337/');

cp4.js

Monday, March 11, 13

Page 117: Einführung in Node.js

CHILD_PROCESS

primeHelper.js

var prime = require('./cp1.js')();

process.send({'prime': prime});

Monday, March 11, 13

Page 118: Einführung in Node.js

CHILD_PROCESS

$ node cp4.js Server running at http://127.0.0.1:1337/incoming Requestincoming RequestRequest answered in: 4242msRequest answered in: 4913ms

Monday, March 11, 13

Page 119: Einführung in Node.js

CHILD_PROCESS

• Threadmodell von Node.js

• Möglichkeiten von child_process - fork, spawn, exec

• Kommunikation zwischen Eltern- und Kindprozess

Monday, March 11, 13

Page 120: Einführung in Node.js

CLUSTER

Monday, March 11, 13

Page 121: Einführung in Node.js

CLUSTER

• Loadbalancing über CPU

• Funktioniert mit allen Instanzen von “net.Server”

• ...auch mit http

Monday, March 11, 13

Page 122: Einführung in Node.js

var cluster = require('cluster'), http = require('http'), workers = 2;

if (cluster.isMaster) { for (var i = 0; i < workers; i++) { cluster.fork(); }} else { console.log('Worker ' + cluster.worker.process.pid + ' started');

http.createServer(function(req, res) {

console.log('Worker ' + cluster.worker.process.pid + ' responds');

res.writeHead(200); res.end("hello world\n"); }).listen(8000);}

cluster.js

Monday, March 11, 13

Page 123: Einführung in Node.js

var http = require('http');

for (var i = 0; i < 100; i++) { http.get('http://localhost:8000', function (res) { console.log(res); });}

clusterClient.js

Monday, March 11, 13

Page 124: Einführung in Node.js

CLUSTER

• node cluster.js

• node clusterClient.js

Monday, March 11, 13

Page 125: Einführung in Node.js

CLUSTERWorker 38128 respondsWorker 38128 respondsWorker 38127 respondsWorker 38127 respondsWorker 38128 respondsWorker 38127 respondsWorker 38128 respondsWorker 38127 respondsWorker 38127 respondsWorker 38127 respondsWorker 38128 respondsWorker 38127 respondsWorker 38128 respondsWorker 38127 respondsWorker 38128 respondsWorker 38127 respondsWorker 38127 respondsWorker 38128 respondsWorker 38127 responds

Monday, March 11, 13

Page 126: Einführung in Node.js

TESTING

Monday, March 11, 13

Page 127: Einführung in Node.js

UNITTESTS

• Absicherung von Applikationen

• Tests auf Funktionsebene

• Node.js testet eigene Module ebenfalls

• Assert-Modul

• node-v0.8.22/test/simple

Monday, March 11, 13

Page 128: Einführung in Node.js

ASSERTION TESTING

Monday, March 11, 13

Page 129: Einführung in Node.js

ASSERTION TESTING

• var assert = require(‘assert’)

• Assertion-Methoden

• Sehr wenig Rückmeldung

• Nur ein Failure

Monday, March 11, 13

Page 130: Einführung in Node.js

ASSERTION TESTINGfail Wirft einen

AssertionErrorok(value, [message]) Pass, wenn der Wert

true istequal(actual, expected, [message]) Vergleich mit ==

deepEqual(actual, expected, [message]) Vergleich über Strukturen

strictEqual(actual, expected, [message]) Vergleich mit ===

throws(block, [error], [message]) Pass, wenn eine Exception geworfen wird

NOT! - notEqual(...)Monday, March 11, 13

Page 131: Einführung in Node.js

ASSERTION TESTING

var assert = require('assert'), actual = 'Hello World', expected = 'Hello World';

assert.equal(actual, expected, 'Strings are not Equal');

assert.notEqual(actual, expected, 'Strings are Equal');

assert.fail('FAIL!', 'PASS!', 'This fails!');

assert.js

Monday, March 11, 13

Page 132: Einführung in Node.js

ASSERTION TESTING

$ node assert.js

assert.js:102 throw new assert.AssertionError({ ^AssertionError: Strings are Equal at Object.<anonymous> (/tmp/node/assert.js:7:8) at Module._compile (module.js:449:26) at Object.Module._extensions..js (module.js:467:10) at Module.load (module.js:356:32) at Function.Module._load (module.js:312:12) at Module.runMain (module.js:492:10) at process.startup.processNextTick.process._tickCallback (node.js:244:9)

Monday, March 11, 13

Page 133: Einführung in Node.js

NODEUNIT

Monday, March 11, 13

Page 134: Einführung in Node.js

NODEUNIT

• npm install -g nodeunit

• Die gleichen Assertion-Methoden wie im Assert-Modul

• More verbose

• Mehrere Failures

Monday, March 11, 13

Page 135: Einführung in Node.js

module.exports = { setUp: function (callback) { console.log('setUp'); callback(); }, tearDown: function (callback) { console.log('tearDown'); callback(); }, firstExample: function (test) { console.log('firstExample') test.equal('Hello', 'Hello', 'Strings are not Equal'); test.done(); }, exampleGroup: { secondExample: function (test) { test.notEqual('Hello', 'Hello', 'Strings are Equal'); test.done(); }, thirdExample: function (test) { test.fail('FAIL!', 'PASS!', 'This fails!'); test.done(); } }}

Monday, March 11, 13

Page 136: Einführung in Node.js

$ nodeunit nodeunit.js

nodeunit.jssetUpfirstExampletearDown✔ firstExamplesetUptearDown✖ exampleGroup - secondExample

Assertion Message: Strings are EqualAssertionError: 'Hello World' != 'Hello World' at Object.assertWrapper [as notEqual] (...

setUptearDown✖ exampleGroup - thirdExample

AssertionError: 'FAIL!' undefined 'PASS!' at Object.assertWrapper [as fail] (...

FAILURES: 2/3 assertions failed (5ms)

Monday, March 11, 13

Page 137: Einführung in Node.js

PROMISES

Monday, March 11, 13

Page 138: Einführung in Node.js

PROMISES

• Ergebnis eines asynchronen Funktionsaufrufs

• Rückgabewert oder Exception

• Promise statt Blocking

• CommonJS Proposal

• Bis 0.2 Bestandteil von Node

Monday, March 11, 13

Page 139: Einführung in Node.js

PYRAMID OF DOOM

step1(function (value1) { step2(value1, function (value2) { step3(value2, function (value3) { step3(value3, function (value4) { // do something }); }); });});

Monday, March 11, 13

Page 140: Einführung in Node.js

PROMISES

Q.fcall(step1) .then(step2) .then(step3) .then(step4) .then(function (value4) { // do something with value 4 }, function (error) { // Handle any error from step1 through step4 }) .end();

Monday, March 11, 13

Page 141: Einführung in Node.js

PROMISE-LIBRARIES

• https://github.com/kriskowal/q

• https://github.com/kriszyp/node-promise (lightweight)

• https://github.com/kriszyp/promised-io (complete API)

• ...

Monday, March 11, 13

Page 142: Einführung in Node.js

OHNE PROMISESvar fs = require('fs');

fs.exists('input.txt', function (exists) { fs.stat('input.txt', function (err, stats) { fs.open('input.txt', 'r+', function (err, fd) { fs.read(fd, new Buffer(stats.size), 0, stats.size, null, function (err, read, buff) { if (err) throw err; console.log(buff.toString()); fs.close(fd, function () { console.log('File Handle closed'); }); } ) }); });});

Monday, March 11, 13

Page 143: Einführung in Node.js

MIT PROMISES

Monday, March 11, 13

Page 144: Einführung in Node.js

var fs = require('promised-io/fs'), gStat, gFd;

var open = function (stat) { gStat = stat; return fs.open('input.txt', 'r+'); }, read = function (fd) { gFd = fd; return fs.read(fd, new Buffer(gStat.size), 0, gStat.size, null); }, close = function (args) { console.log(args[1].toString()); return fs.close(gFd); }, catchall = function (err) { console.log(err); }, finished = function () { console.log('File Handle closed'); };

fs.stat('input.txt') .then(open) .then(read) .then(close) .then(finished, catchall);Monday, March 11, 13

Page 145: Einführung in Node.js

AUSFÜHRUNG

$ node promises2.js Hello World

File Handle closed

Monday, March 11, 13

Page 146: Einführung in Node.js

JETZT HABT IHR’S GESCHAFFT

Monday, March 11, 13

Page 147: Einführung in Node.js

FRAGEN?

Monday, March 11, 13

Page 148: Einführung in Node.js

KONTAKT

Sebastian [email protected]

Mayflower GmbHMannhardtstr. 680538 MünchenDeutschland

@basti_springer

https://github.com/sspringer82

Monday, March 11, 13

Page 149: Einführung in Node.js

OHNE PROMISES

Monday, March 11, 13

Page 150: Einführung in Node.js

OHNE PROMISES

Monday, March 11, 13

Page 151: Einführung in Node.js

PROMISES

Monday, March 11, 13

Page 152: Einführung in Node.js

PROMISES

Monday, March 11, 13

Page 153: Einführung in Node.js

PROMISES

Monday, March 11, 13

Page 154: Einführung in Node.js

PROMISES

Monday, March 11, 13