• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Introduction to Nodejs
 

Introduction to Nodejs

on

  • 13,453 views

Introduction to Nodejs with examples

Introduction to Nodejs with examples

Statistics

Views

Total Views
13,453
Views on SlideShare
9,539
Embed Views
3,914

Actions

Likes
23
Downloads
376
Comments
0

18 Embeds 3,914

http://www.maestrosdelweb.com 3762
http://integradorweb.com 81
http://mdw.diegoescares.com 16
http://feeds.feedburner.com 15
http://lanyrd.com 12
http://flavors.me 7
http://translate.google.com 5
http://inteligenciaartificialomb.com 4
http://webcache.googleusercontent.com 2
http://foros.collected.info 2
http://127.0.0.1:8795 1
http://www.newsblur.com 1
http://localhost 1
http://translate.googleusercontent.com 1
http://www.poclu.com 1
https://www.google.com 1
http://www.red-geek.com.ar 1
https://twitter.com 1
More...

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Introduction to Nodejs Introduction to Nodejs Presentation Transcript

    • verona21/05/2011
    • gabriele lanagabriele.lana@cleancode.it twitter: @gabrielelana
    • why node.js?“Nodes goal is to provide an easy way to buildscalable network programs” http://nodejs.org/#about
    • what is node.js?• asynchronous i/o framework• core in c++ on top of v8• rest of it in javascript• swiss army knife for network related stuffs• can handle thousands of concurrent connections with minimal overhead (cpu/memory) on a single process
    • Single threadsynchronous I/0
    • Single threadsynchronous I/0
    • multiple threadsynchronous I/0
    • multiple threadsynchronous I/0
    • you can “always” scale with multiplemachines but it costs you $$$
    • but...what is HE doing?
    • CPU BOUND TASKS? but...what is HE doing?
    • CPU BOUND TASKS? ...OR I/o but... BOUNDwhat is HE TASKS? doing?
    • synchronous I/0function productsInCart(request, response) { var db = new Db() var user = new User(request) if (user.isAuthorized("cart/products")) { response.write( JSON.stringify( db.productsInCart(user.cartId()) ) ) } else { response.unauthorized() }}
    • synchronous I/0function productsInCart(request, response) { var db = new Db() var user = new User(request) if (user.isAuthorized("cart/products")) { response.write( JSON.stringify( db.productsInCart(user.cartId()) ) ) } else { response.unauthorized() }}
    • synchronous I/0function productsInCart(request, response) { var db = new Db() var user = new User(request) if (user.isAuthorized("cart/products")) { response.write( JSON.stringify( db.productsInCart(user.cartId()) ) ) } else { response.unauthorized() }}
    • synchronous I/0function productsInCart(request, response) { var db = new Db() var user = new User(request) if (user.isAuthorized("cart/products")) { response.write( JSON.stringify( db.productsInCart(user.cartId()) ) ) } else { response.unauthorized() }}
    • single threadasynchronous I/0
    • single threadasynchronous I/0 I am “callback” call me if you need me...
    • hello_world_server.js Event Emitter var http = require("http") var server = http.createServer(function(request, response) { response.writeHead(200, { "Content-Type": "plain/text" }) response.write("Hello Worldn") response.end() }) server.listen(8080) console.log("> SERVER STARTED")
    • hello_world_server.js Event Emitter var http = require("http") var server = http.createServer(function(request, response) { response.writeHead(200, { "Content-Type": "plain/text" }) response.write("Hello Worldn") response.end() }) server.listen(8080) console.log("> SERVER STARTED")
    • hello_world_server.js Event Emitter var http = require("http") var server = http.createServer(function(request, response) { response.writeHead(200, { "Content-Type": "plain/text" }) response.write("Hello Worldn") response.end() }) server.listen(8080) console.log("> SERVER STARTED")
    • hello_world_server.js Event Emitter var http = require("http") var server = http.createServer(function(request, response) { response.writeHead(200, { "Content-Type": "plain/text" }) response.write("Hello Worldn") response.end() }) server.listen(8080) console.log("> SERVER STARTED")
    • Event Emittercoder@apollo:~/Work/src/node/examples$ node hello_world_server.js> SERVER STARTED #1coder@apollo:~$ curl "http://localhost:8080/"Hello World #2
    • Event Emitter var server = require("http").createServer()hello_world_server.js server.on("request", function(request, response) { console.log("> REQUEST STARTED") request.on("end", function() { console.log("> REQUEST CLOSED") response.writeHead(200, { "Content-Type": "plain/text" }) response.end("Hello Worldn") server.close() }) response.on("close", function() { console.log("> RESPONSE CLOSED") }) })
    • hello_world_server.js Event Emitter ... server.on("close", function() { console.log("> SERVER CLOSED") }) server.on("listening", function() { console.log("> SERVER STARTED") }) server.listen(8080)
    • Event Emittercoder@apollo:~/Work/src/node/examples$ node hello_world_server.js> SERVER STARTED #1coder@apollo:~$ curl "http://localhost:8080/"Hello World #2 #1> REQUEST STARTED> REQUEST CLOSED> SERVER CLOSED
    • why socomplicated?
    • data streamS server.on("request", function(request, response) { var chunks = [], output = fs.createWriteStream("./output")proxy_stream.js request.on("data", function(chunk) { chunks = forEachLine(chunks.concat(chunk), function(line) { output.write(parseInt(line, 10) * 2) output.write("n") }) }) request.on("end", function() { response.writeHead(200, { "Content-Type": "plain/text" }) response.end("OKn") output.end() server.close() }) })
    • data streamScoder@apollo:~/Work/src/node/examples$ node stream_doubler.js #1coder@apollo:~$ curl "http://localhost:8080/" --data $1n2n3nOK #2coder@apollo:~/Work/src/node/examples$ cat output246 #1
    • why javascript?• Friendly callbacks• ubiquitous (well known)• no I/o primitives• one language to rule them all
    • web applications before: a webmind shift #1 server with some application logic application Web server application application application
    • web applications after: an applicationmind shift #1 accessible over http web server application
    • web applications after: an applicationmind shift #1 that can communicate and collaborate with the world web server application
    • web applications before: statefulmind shift #2 • no easy to scale • no easy to reuse v M c
    • web applications before: statefulmind shift #2 • no easy to scale • no easy to reuse v M c conversation application state state
    • web applications before: statefulmind shift #2 • no easy to scale • no easy to reuse v M c tightly coupled
    • web applications after: statelessmind shift #2 • easy to scale • easy to reuse v http M c
    • web applications after: statelessmind shift #2 • easy to scale • easy to reuse v http M cconversation application state state
    • web applications after: statelessmind shift #2 http web server M http statefull connection• easy to scale M• easy to reuse
    • no fluffjust stuff
    • What aboutcpu bound tasks?
    • the forklong_running_job.sh be with you #!/bin/bash for count in `seq 1 100`; do echo $count sleep 0.1 done
    • the forklong_running_server.js be with you var spawn = require("child_process").spawn, server = require("http").createServer() server.on("request", function(request, response) { var job = spawn("./long_running_job.sh") job.stdout.on("data", function(tick) { response.write(tick) }) job.on("exit", function() { response.end() }) })
    • the fork be with youcoder@apollo:~$ ab -c 1 -n 1 "http://localhost:8080/"...Concurrency Level: 1Time taken for tests: 10.531 seconds...coder@apollo:~$ ab -c 1 -n 2 "http://localhost:8080/"...Concurrency Level: 1Time taken for tests: 20.108 seconds...
    • the fork be with youcoder@apollo:~$ ab -c 2 -n 1 "http://localhost:8080/"...Concurrency Level: 2Time taken for tests: 10.634 seconds...coder@apollo:~$ ab -c 100 -n 100 "http://localhost:8080/"...Concurrency Level: 100Time taken for tests: 11.198 seconds...coder@apollo:~$ ab -c 500 -n 500 "http://localhost:8080/"...Concurrency Level: 500Time taken for tests: 31.082 seconds...
    • enter cometw at chwatch M spawn ch atw watch w w t a at ch ch
    • enter cometdemo
    • INSTALL NPM (node packet manager)coder@apollo:~/Work/src/node/examples$ curl http://npmjs.org/install.sh | sh...npm okIt workedcoder@apollo:~/Work/src/node/examples$ npm search | wc -l1918coder@apollo:~/Work/src/node/examples$ npm install connect socket.io underscorecoder@apollo:~/Work/src/node/examples$ npm list!"# connect@1.4.1$ !"" mime@1.2.2$ %"" qs@0.1.0%"" socket.io@0.6.17%"" underscore@1.1.6
    • server/ routingprogress_server.js var server = connect( connect.favicon(), connect.logger({"buffer": true}), connect.router(function(resource) { resource.post("/spawn", function(request, response) { ... }) }), connect.static(path.join(__dirname, "public"), {"cache": true}) )
    • server/ routingprogress_server.js resource.post("/spawn", function(request, response) { var job = spawn(path.join(__dirname, "bin", "job.sh")), id = ++counter response.writeHead(202, {"Content-Type": "plain/text"}) response.end("OKn") job.stdout.on("data", function(output) { var progress = parseInt(output.toString(), 10) _(connections).each(function(connection) { connection.send({"id": id, "progress": progress}) }) }) })
    • server/ socket.ioprogress_server.js io.listen(server).on("connection", function(client) { connections[client.sessionId] = client client.on("disconnect", function() { delete connections[client.sessionId] }) })
    • server/ simulationprogress_server.js server.listen(port, host, function() { var spawnJobsInterval = setInterval(function() { http.request({ "port": port, "host": host, "method": "POST", "path": "/spawn" }).end() }, Math.floor(Math.random()*2000)+500) server.on("close", function() { clearInterval(spawnJobsInterval) process.exit() }) }) process.on("SIGINT", function() { server.close() })
    • interface/html <html> <head> <title>Node.js - Long Running Jobs</title> <link href="css/style.css" rel="stylesheet" /> <script type="text/javascript" src="/socket.io/socket.io.js"></script> <script type="text/javascript" src="js/jquery-1.6.0.js"></script> <script type="text/javascript" src="js/progress.js"></script>index.html </head> <body> <div id="template"> <div class="progress-container"> <span class="progress-text">JOB/? - ?%</span> <div class="progress-bar"></div> </div> </div> <div id="container"> </div> </body> <script> ... </script> </html>
    • interface/ socket.io <html> ... <script> $(function() { var socket = new io.Socket()index.html socket.on("connect", function() { }) socket.on("disconnect", function() { }) socket.on("message", function(job) { $("#template").progressBar(job.id, job.progress) }) socket.connect() }) </script> </html>
    • interface/ progress bar $.fn.progressBar = function(id, progress) { var $template = $(this) $("#job-" + id) .otherwise(function() { return $template.children().clone()progress.js .attr("id", "job-" + id) .find(".progress-text").text("JOB/" + id + " - 0%").end() .appendTo("#container") }) .find(".progress-text").text("JOB/" + id + " - " + progress + "%").end() .find(".progress-bar").css("width", progress + "%").end() .tap(function() { if (progress === 100) { $(this) .find(".progress-bar").css("background-color", "red").end() .after(500, function() { $(this).fadeOut("slow", function() { $(this).remove() }) }) }
    • interface/ progress bar $.fn.otherwise = function(ifNotFound) { if (this.length === 0) { return ifNotFound() }progress.js return this } $.fn.after = function(milliseconds, doSomething) { var self = this setTimeout(function() { doSomething.apply(self) }, milliseconds) return this } $.fn.tap = function() { var fn = Array.prototype.shift.apply(arguments) fn.apply(this, arguments) return this }
    • we can do itwith a littlemore “style”
    • server/ event emitter var Job = (function() { var EventEmitter = require("events").EventEmitter,progress_server.js spawn = require("child_process").spawn, inherits = require("util").inherits function Job(id) { EventEmitter.call(this) this.id = id } inherits(Job, EventEmitter) Job.prototype.run = function() { return _(this).tap(function(job) { spawn(path.join(__dirname, "bin", "job.sh")) .stdout.on("data", function(output) { job.emit("progress", job.id, parseInt(output.toString(), 10)) }) }) } return Job })()
    • server/ event emitterprogress_server.js resource.post("/spawn", function(request, response) { new Job(++counter) .on("progress", function(id, progress) { _(connections).each(function(connection) { connection.send({"id": id, "progress": progress}) }) }) .run() response.writeHead(202, { "Content-Type": "plain/text" }) response.end("OKn") })
    • node.js is awesome but when should i use it?
    • when to use it?• chat/messaging• real-time applications• intelligent proxies• high concurrency applications• communication hubs• coordinators
    • please tellme something bad about node.js
    • some warnings• release stable 0.4.7 (young)• lots of stuffs to look at• lots of half backed stuffs• retro compatibility???• bad at handling static contents• Bad at handling binary contents• hard to find organized and authoritative informations
    • vs
    • Questions?
    • gabriele lana gabriele.lana@cleancode.it twitter: @gabrielelanahttp://joind.in/3359