this presentation code is on
https://github.com/gabrielelana/node-examples
gabriele lana
  gabriele.lana@cleancode.it
    twitter: @gabrielelana
         this presentation code is on
https://github...
why
         node.js?

“Node's goal is to
  provide an easy
   way to build
scalable network
    programs”

           htt...
what is
                  node.js?
•   asynchronous i/o framework
•   core in c++ on top of v8
•   rest of it in javascrip...
Single thread
synchronous I/0
Single thread
synchronous I/0
multiple thread
synchronous I/0
multiple thread
synchronous I/0
you can
  “always”
 scale with
  multiple
machines but
  it costs
  you $$$
but...
what is HE
 doing?
CPU BOUND
          TASKS?


  but...
what is HE
 doing?
CPU BOUND
          TASKS?

             ...OR I/o
  but...       BOUND
what is HE    TASKS?
 doing?
synchronous I/0

function
productsInCart(request,
response)
{




var
db
=
new
Db()




var
user
=
new
User(request)




i...
synchronous I/0

function
productsInCart(request,
response)
{




var
db
=
new
Db()




var
user
=
new
User(request)




i...
synchronous I/0

function
productsInCart(request,
response)
{




var
db
=
new
Db()




var
user
=
new
User(request)




i...
synchronous I/0

function
productsInCart(request,
response)
{




var
db
=
new
Db()




var
user
=
new
User(request)




i...
single thread
asynchronous I/0
single source events
  STATES




                      EVENTS
http://www.infoq.com/presentations/Death-by-Accidental-Comp...
single source events
 function
productsInCart(request,
response)
{
 



var
db
=
null,
user
=
null,
...
 



createDb()
 
...
asynchronous I/0
  single thread
asynchronous I/0


           I am
       “callback”
         call me
         if you
   ...
asynchronous I/0
  single thread
asynchronous I/0
multiple source events
     (local state)
STATES




         EVENTS
multiple source events
     (local state)
  function
productsInCart(request,
response)
{
  



createDb(function(db)
{
  
...
multiple source events
     (local state)
  function
productsInCart(request,
response)
{
  



createDb(function(db)
{
  
...
Event Emitter
                         (local state)
var
http
=
require("http")

var
server
=
http.createServer(function(r...
Event Emitter
                         (local state)
var
http
=
require("http")

var
server
=
http.createServer(function(r...
Event Emitter
                         (local state)
var
http
=
require("http")

var
server
=
http.createServer(function(r...
Event Emitter
                         (local state)
var
http
=
require("http")

var
server
=
http.createServer(function(r...
Event Emitter
                                (local state)
coder@apollo:~/Work/src/node/examples$ node hello_world_server...
Event Emitter
                         (local state)
var
server
=
require("http").createServer()

server.on("request",
fun...
Event Emitter
                         (local state)

...

server.on("close",
function()
{


console.log(">
SERVER
CLOSED"...
Event Emitter
                                (local state)
coder@apollo:~/Work/src/node/examples$ node hello_world_server...
why so
complicated?
data streams
server.on("request",
function(request,
response)
{


var
chunks
=
[],






output
=
fs.createWriteStream("./...
Event Emitter
                                (local state)
coder@apollo:~/Work/src/node/examples$ node stream_doubler.js
...
why
                 javascript?


•   Friendly callbacks
•   ubiquitous (well known)
•   no I/o primitives
•   one langua...
web applications
                             before: a web
mind shift #1               server with some
                 ...
web applications
                        after: an application
mind shift #1             accessible over
                 ...
web applications
                        after: an application
mind shift #1                 that can
                    ...
web applications
                    before: stateful
mind shift #2   • no easy to scale
                • no easy to reus...
web applications
                    before: stateful
mind shift #2   • no easy to scale
                • no easy to reus...
web applications
                    before: stateful
mind shift #2   • no easy to scale
                • no easy to reus...
web applications
                    after: stateless
mind shift #2      • easy to scale
                   • easy to reus...
web applications
                    after: stateless
mind shift #2      • easy to scale
                   • easy to reus...
web applications
                       after: stateless
mind shift #2
                http




                       web...
no fluff
just stuff
tic - tac - toe
tic - tac - toe



demo
INSTALL NPM
                                   (node packet manager)

coder@apollo:~/Work/src/node/examples$ curl http://n...
game handler
                           (generate board-id)






resource.post("/board",
function(request,
response)
{


...
game handler
                              (initial board/user)




resource.get("/board/:id",
function(request,
response)...
game handler
                                 (make your move)







resource.post("/board/:id",
function(request,
respon...
comet handler

var
comet
=
new
Faye.NodeAdapter({
"mount":
"/comet",
"timeout":
50
})

var
server
=
connect.createServer(c...
comet EVENTS
                       on backbone events



var
client
=
comet.getClient()
var
boards
=
new
Backbone.Collect...
in browser
                                     routing

$(function()
{



$.sammy(function()
{









this.get("",
func...
in browser
                                 routing/start game





var
comet
=
new
Faye.Client("/comet")




var
game
=
n...
in browser
                             game logic example




window.Game
=
Backbone.Model.extend({




"initialize":
fun...
in browser
                              game logic example




game.bind("play-with-board",
function(cells)
{






build...
What about
cpu bound
  tasks?
the fork
                               be with you


#!/bin/bash

for
count
in
`seq
1
100`;
do




echo
$count




sleep
...
the fork
                                be with you
var
spawn
=
require("child_process").spawn,




server
=
require("htt...
the fork
                                     be with you
coder@apollo:~$ ab -c 1 -n 1 "http://localhost:8080/"
...
Concur...
the fork
                                     be with you
coder@apollo:~$ ab -c 2 -n 1 "http://localhost:8080/"
...
Concur...
enter comet


w
 at
 at ch
watch
    ch
                M                spawn
w




                watch
            w

...
enter comet



demo
static handler

var
port
=
8080

var
server
=
connect.createServer(connect.logger())


.use("/comet",
function(request,
re...
comet handler


var
comet
=
new
Faye.NodeAdapter({


"mount":
"/comet",
"timeout":
50

})

var
server
=
connect.createServ...
in browser

<script>


$(function()
{




var
comet
=
new
Faye.Client("/comet")





comet.connect()




comet.subscribe("...
node.js is
 awesome
 but when
 should i
  use it?
when to use it?

•   chat/messaging
•   real-time applications
•   intelligent proxies
•   high concurrency applications
•...
please tell
me something
 bad about
  node.js
some warnings

•   release stable 0.2.4 (young)
•   lots of stuffs to look at
•   lots of half backed stuffs
•   retro com...
Questions?
gabriele lana
  gabriele.lana@cleancode.it
    twitter: @gabrielelana
         this presentation code is on
https://github...
Nodejs Explained with Examples
Nodejs Explained with Examples
Nodejs Explained with Examples
Nodejs Explained with Examples
Upcoming SlideShare
Loading in...5
×

Nodejs Explained with Examples

111,092

Published on

Nodejs Explained with Examples

Published in: Technology
7 Comments
86 Likes
Statistics
Notes
No Downloads
Views
Total Views
111,092
On Slideshare
0
From Embeds
0
Number of Embeds
5
Actions
Shares
0
Downloads
1,511
Comments
7
Likes
86
Embeds 0
No embeds

No notes for slide

Transcript of "Nodejs Explained with Examples"

  1. 1. this presentation code is on https://github.com/gabrielelana/node-examples
  2. 2. gabriele lana gabriele.lana@cleancode.it twitter: @gabrielelana this presentation code is on https://github.com/gabrielelana/node-examples
  3. 3. why node.js? “Node's goal is to provide an easy way to build scalable network programs” http://nodejs.org/#about
  4. 4. 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
  5. 5. Single thread synchronous I/0
  6. 6. Single thread synchronous I/0
  7. 7. multiple thread synchronous I/0
  8. 8. multiple thread synchronous I/0
  9. 9. you can “always” scale with multiple machines but it costs you $$$
  10. 10. but... what is HE doing?
  11. 11. CPU BOUND TASKS? but... what is HE doing?
  12. 12. CPU BOUND TASKS? ...OR I/o but... BOUND what is HE TASKS? doing?
  13. 13. synchronous I/0 function
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() 



} }
  14. 14. synchronous I/0 function
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() 



} }
  15. 15. synchronous I/0 function
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() 



} }
  16. 16. synchronous I/0 function
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() 



} }
  17. 17. single thread asynchronous I/0
  18. 18. single source events STATES EVENTS http://www.infoq.com/presentations/Death-by-Accidental-Complexity
  19. 19. single source events function
productsInCart(request,
response)
{ 



var
db
=
null,
user
=
null,
... 



createDb() 



handle(function(source,
event)
{ 







if
(event["name"]
===
"createDb")
{ 











if
(db
===
null)
{ 















db
=
event.data 















createUser(request) 











}
else
{ 















???? 











} 







}
else
if
(event["name"]
===
"createUser")
{ 











if
(user
===
null)
{ 















user
=
event.data 















... 











}
else
{ 















??? 











} 







...
 







}
else
{ 











source.push(event,
state) 







} 



},
"_initial") }
  20. 20. asynchronous I/0 single thread asynchronous I/0 I am “callback” call me if you need me...
  21. 21. asynchronous I/0 single thread asynchronous I/0
  22. 22. multiple source events (local state) STATES EVENTS
  23. 23. multiple source events (local state) function
productsInCart(request,
response)
{ 



createDb(function(db)
{ 







createUser(function(user)
{ 











if
(user.isAuthorized("cart/products")
{ 















response.write( 



















JSON.stringify( 























db.productsInCart(user.cartId()) 



















) 















) 















response.end() 











})
else
{ 















response.unauthorized() 











} 







}) 



}) }
  24. 24. multiple source events (local state) function
productsInCart(request,
response)
{ 



createDb(function(db)
{ 







createUser(function(user)
{ 











if
(user.isAuthorized("cart/products")
{ 















response.write( 



















JSON.stringify( 























db.productsInCart(user.cartId()) 



















) 















) 















response.end() 











})
else
{ 















response.unauthorized() 











} 







}) 



}) }
  25. 25. Event Emitter (local state) 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") 01#hello_world/hello_world_server.js
  26. 26. Event Emitter (local state) 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") 01#hello_world/hello_world_server.js
  27. 27. Event Emitter (local state) 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") 01#hello_world/hello_world_server.js
  28. 28. Event Emitter (local state) 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") 01#hello_world/hello_world_server.js
  29. 29. Event Emitter (local state) coder@apollo:~/Work/src/node/examples$ node hello_world_server.js > SERVER STARTED #1 coder@apollo:~$ curl "http://localhost:8080/" Hello World #2
  30. 30. Event Emitter (local state) var
server
=
require("http").createServer() 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") 

}) }) 01#hello_world/hello_world_server_emitter.js
  31. 31. Event Emitter (local state) ... server.on("close",
function()
{ 

console.log(">
SERVER
CLOSED") }) server.on("listening",
function()
{ 

console.log(">
SERVER
STARTED") }) server.listen(8080) 01#hello_world/hello_world_server_emitter.js
  32. 32. Event Emitter (local state) coder@apollo:~/Work/src/node/examples$ node hello_world_server.js > SERVER STARTED #1 coder@apollo:~$ curl "http://localhost:8080/" Hello World #2 #1 > REQUEST STARTED > REQUEST CLOSED > SERVER CLOSED
  33. 33. why so complicated?
  34. 34. data streams server.on("request",
function(request,
response)
{ 

var
chunks
=
[], 





output
=
fs.createWriteStream("./output") 

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

}) }) 02#proxy_stream/proxy_stream.js
  35. 35. Event Emitter (local state) coder@apollo:~/Work/src/node/examples$ node stream_doubler.js #1 coder@apollo:~$ curl "http://localhost:8080/" --data $'1n2n3n' OK #2 coder@apollo:~/Work/src/node/examples$ cat output 2 4 6 #1
  36. 36. why javascript? • Friendly callbacks • ubiquitous (well known) • no I/o primitives • one language to rule them all
  37. 37. web applications before: a web mind shift #1 server with some application logic application Web server application application application
  38. 38. web applications after: an application mind shift #1 accessible over http web server application
  39. 39. web applications after: an application mind shift #1 that can communicate and collaborate with web server the world application
  40. 40. web applications before: stateful mind shift #2 • no easy to scale • no easy to reuse v M c
  41. 41. web applications before: stateful mind shift #2 • no easy to scale • no easy to reuse v M c conversation application state state
  42. 42. web applications before: stateful mind shift #2 • no easy to scale • no easy to reuse v M c tightly coupled
  43. 43. web applications after: stateless mind shift #2 • easy to scale • easy to reuse v http M c
  44. 44. web applications after: stateless mind shift #2 • easy to scale • easy to reuse v http M c conversation application state state
  45. 45. web applications after: stateless mind shift #2 http web server M http statefull connection • easy to scale M • easy to reuse
  46. 46. no fluff just stuff
  47. 47. tic - tac - toe
  48. 48. tic - tac - toe demo
  49. 49. INSTALL NPM (node packet manager) coder@apollo:~/Work/src/node/examples$ curl http://npmjs.org/install.sh | sh ... npm ok It worked coder@apollo:~/Work/src/node/examples$ npm list | wc -l 1776 coder@apollo:~/Work/src/node/examples$ npm install connect@0.2.5 coder@apollo:~/Work/src/node/examples$ npm install faye@0.5.3 coder@apollo:~/Work/src/node/examples$ npm install backbone@0.3.0 coder@apollo:~/Work/src/node/examples$ npm install underscore@1.1.2
  50. 50. static handler var
server
=
connect.createServer(connect.logger({
"buffer":
true
})) 

.use("/",
connect.router(function(resource)
{ 



resource.get("/board",
function(request,
response,
next)
{ 





request.url
=
"/board.html" 





next() 



}) 



... 

}),
connect.staticProvider({
 



"root":
path.join(__dirname,
"static"),
 



"cache":
true
 

})) server.listen(port) 05#tictactoe/server.js
  51. 51. game handler (generate board-id) 



resource.post("/board",
function(request,
response)
{ 





response.writeHead(200,
{
"Content-Type":
"application/json"
}) 





uuid(function(boardId)
{ 







response.end( 









JSON.stringify({ 











"board":
{
"id":
boardId
} 









}) 







) 





}) 



}) 05#tictactoe/server.js
  52. 52. game handler (initial board/user) 



resource.get("/board/:id",
function(request,
response)
{ 





var
board
=
boards.get(request.params["id"]) 





if
(board
===
undefined)
{ 







board
=
new
Board({
"id":
request.params["id"]
}) 







boards.add(board) 





} 





uuid(function(userId)
{ 







var
user
=
board.user(userId) 







response.writeHead(200,
{
"Content-Type":
"application/json"
}) 







response.end( 









JSON.stringify({ 











"board":
board, 











"user":
user 









}) 







) 





}) 



}) 05#tictactoe/server.js
  53. 53. game handler (make your move) 



resource.post("/board/:id",
function(request,
response)
{ 





waitForBody(request,
function(body)
{ 







boards.get(request.params["id"]).move(JSON.parse(body)) 







response.writeHead(204,
{
"Content-Type":
"application/json"
}) 







response.end(JSON.stringify({
"response":
"ok"
})) 





}) 



}) 05#tictactoe/server.js
  54. 54. comet handler var
comet
=
new
Faye.NodeAdapter({
"mount":
"/comet",
"timeout":
50
}) var
server
=
connect.createServer(connect.logger({
"buffer":
true
})) 

.use("/comet",
function(request,
response,
next)
{ 



comet.handle(request,
response) 

}) 

... }) comet.attach(server) 05#tictactoe/server.js
  55. 55. comet EVENTS on backbone events var
client
=
comet.getClient() var
boards
=
new
Backbone.Collection boards.bind("change",
function(board)
{ 

client.publish("/board-"
+
board.get("id"),
board) }) 05#tictactoe/server.js
  56. 56. in browser routing $(function()
{ 

$.sammy(function()
{ 



 



this.get("",
function(context)
{ 





$.post("/board",
function(response)
{ 







context.redirect("#/board/"
+
response["board"]["id"]) 





}) 



}) 



... 

}).run() }) 05#tictactoe/static/board.html
  57. 57. in browser routing/start game 



var
comet
=
new
Faye.Client("/comet") 



var
game
=
new
Game() 



this.get("#/board/:id",
function(context)
{ 





game.start() 





$.get("/board/"
+
context.params["id"],
function(response)
{ 







game.set({
"me":
new
User(response.user)
}) 







game.set({
"board":
new
Board(response.board)
}) 







comet.connect() 







comet.subscribe("/board-"
+
context.params["id"],
function(board)
{ 









game.get("board").set(board) 







}) 





}) 



}) 05#tictactoe/static/board.html
  58. 58. in browser game logic example 

window.Game
=
Backbone.Model.extend({ 



"initialize":
function()
{ 





... 





game.get("board").bind("change",
function()
{ 







if
(this.isMyTurn())
{ 









return
game.trigger("make-your-move") 







} 







return
game.trigger("wait-for-move") 





}) 



} 

}) 05#tictactoe/static/js/application.js
  59. 59. in browser game logic example 



game.bind("play-with-board",
function(cells)
{ 





buildBoard(['_'].concat(cells)) 



}) 



game.bind("play-with-mark",
function(mark)
{ 





showPlayerMarker(cellMarksUrl[myMark
=
mark]) 



}) 



game.bind("make-your-move",
function()
{ 





$("#board").undelegate() 





$("#board").delegate("*[id^=cell]",
"mouseover",
function()
{ 







$(this).data("cell").select() 





}) 





$("#board").delegate("*[id^=cell]",
"mouseout",
function()
{ 







$(this).data("cell").unselect() 





}) 





... 05#tictactoe/static/js/application.js
  60. 60. What about cpu bound tasks?
  61. 61. the fork be with you #!/bin/bash for
count
in
`seq
1
100`;
do 



echo
$count 



sleep
0.1 done 03#long_running_jobs/long_running_job.sh
  62. 62. the fork 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() 

}) }) 03#long_running_jobs/long_running_server.js
  63. 63. the fork be with you coder@apollo:~$ ab -c 1 -n 1 "http://localhost:8080/" ... Concurrency Level: 1 Time taken for tests: 10.531 seconds ... coder@apollo:~$ ab -c 1 -n 2 "http://localhost:8080/" ... Concurrency Level: 1 Time taken for tests: 20.108 seconds ...
  64. 64. the fork be with you coder@apollo:~$ ab -c 2 -n 1 "http://localhost:8080/" ... Concurrency Level: 2 Time taken for tests: 10.634 seconds ... coder@apollo:~$ ab -c 100 -n 100 "http://localhost:8080/" ... Concurrency Level: 100 Time taken for tests: 11.198 seconds ... coder@apollo:~$ ab -c 500 -n 500 "http://localhost:8080/" ... Concurrency Level: 500 Time taken for tests: 31.082 seconds ...
  65. 65. enter comet w at at ch watch ch M spawn w watch w w t a at ch ch
  66. 66. enter comet demo
  67. 67. static handler var
port
=
8080 var
server
=
connect.createServer(connect.logger()) 

.use("/comet",
function(request,
response)
{
...
}) 

.use("/spawn",
function(request,
response)
{
...
}) 

.use("/",
connect.staticProvider({
 



"root":
path.join(__dirname,
"static"),
 



"cache":
true
 

})) comet.attach(server) server.listen(port) 04#progress/progress_server.js
  68. 68. comet handler var
comet
=
new
Faye.NodeAdapter({ 

"mount":
"/comet",
"timeout":
50
 }) var
server
=
connect.createServer(connect.logger()) 

.use("/comet",
function(request,
response,
next)
{ 



comet.handle(request,
response) 

}) 

... 04#progress/progress_server.js
  69. 69. spawn handler var
client
=
comet.getClient(),
jobCounter
=
0 var
server
=
connect.createServer(connect.logger()) 

.use("/comet",
function(request,
response)
{
...
}) 

.use("/spawn",
function(request,
response,
next)
{ 



var
worker
=
spawn("./long_running_process.sh"), 







jobId
=
jobsCounter++ 







 



response.writeHead(200,
{
"Content-Type":
"plain/text"
}) 



response.end("OKn") 



worker.stdout.on("data",
function(progress)
{ 





client.publish("/job-progress",
{
 







"id":
jobId,
 







"progress":
parseInt(progress.toString(),
10) 





}) 



}) 

}) 04#progress/progress_server.js
  70. 70. in browser <script> 

$(function()
{ 



var
comet
=
new
Faye.Client("/comet") 



comet.connect() 



comet.subscribe("/job-progress",
function(job)
{ 





$("#template").progressBar(job.id,
job.progress) 



}) 

}) </script> 04#progress/static/index.html
  71. 71. node.js is awesome but when should i use it?
  72. 72. when to use it? • chat/messaging • real-time applications • intelligent proxies • high concurrency applications • communication hubs • coordinators
  73. 73. please tell me something bad about node.js
  74. 74. some warnings • release stable 0.2.4 (young) • lots of stuffs to look at • lots of half backed stuffs • retro compatibility??? • bad at handling static contents • hard to find organized and authoritative informations
  75. 75. Questions?
  76. 76. gabriele lana gabriele.lana@cleancode.it twitter: @gabrielelana this presentation code is on https://github.com/gabrielelana/node-examples

×