SlideShare a Scribd company logo
Node.js Tutorial
Tom Hughes-Croucher, Principal
Jetpacks For Dinosaurs, LLC

tom@jetpacksfordinosaurs.com
@sh1mmer
Introduction
•   Tom Hughes-Croucher
•   Principal at Jetpacks for Dinosaurs
•   Node.js and High-performance web site
    consulting and training
•   Walmart, MySpace, Joyent,Yahoo!, NASA, Tesco,
    etc
•   Node.js contributor
•   Lead author of "Node: Up and Running"
Scalable Server-Side Code with JavaScript




                Node                       Up and Running




                                          Tom Hughes-Croucher




  http://ofps.oreilly.com/titles/9781449398583/
http://shop.oreilly.com/product/0636920015956.do
Training
  Online




 In person
Node refresher
Code!
Interactive Debugging
Enki:~/Code/node-examples $ node --debug
helloworld.js
debugger listening on port 5858
Server running at http://127.0.0.1:8124/
enki:~ sh1mmer$ ps -A | grep node
19093 ttys001 0:00.39 node index.js
19273 ttys002 0:00.00 grep node
enki:~ sh1mmer$ kill -s USR1 19093
enki:~ sh1mmer$ node index.js
Hit SIGUSR1 - starting debugger agent.
debugger listening on port 5858
Enki:~ $ sudo npm install -g node-inspector
node-inspector@0.1.8 ./node_modules/node-inspector
├── websocket-server@1.4.04
└── paperboy@0.0.2
Enki:~ $ node-inspector
visit http://0.0.0.0:8080/debug?port=5858 to start
debugging
Writing robust Node.js applications
Exercises

• Modify a basic HTTP server to return the
  text "I'm learning Node"
• Change the HTTP response to HTML and
  return your text in an HTML page
• Return the User-Agent string from the
  browser as part of your HTML page
Express.js
Sinatra Style MVC
   framework
var app = require('express').createServer();

app.get('/', function(req, res){
    res.send('hello world');
});

app.listen(3000);
HTTP Verb Oriented
Middleware
app.use(express.bodyParser());
app.use(express.cookieParser());

app.post('/', function(req, res){
  // Perhaps we posted several items with a form
  // (use the bodyParser() middleware for this)
  var items = req.body.items;
  console.log(items);
  res.send('logging');
});
Templating
var express = require("express");

app.configure(function () {
     var public = __dirname + "/../public/";
     public = require("path").normalize(public);

      app.set("views", __dirname + "/views");
      app.set("view engine", "jade");
});

app.get("/", function (req, res) {
     res.render("index", {
        locals : {
           h1: 'Router Stats',
           scripts : [
              "/public/smoothie.js",
              "/public/raphael.js",
              "/public/base.js",
              "/public/gfx.js",
              "/public/explore.js",
              "/public/app.js"
           ]
        }
     }
});
Exercise
• Create an Express server
• Make routes for ‘/’ & ‘/products’
• Serve two different pages based on
  value of the query string parameter
  "page"

• Create a redirect from /old to /new
• Set a cookie on the client
Building a chat server
Node Architectures
The obvious
architecture
Client   Front-end   Database




User       Node        DB
What about this?
Heavy
         Front-end
Client               Processor   Database
           Farm
                       Work



User       Node
           Node       Node
                      Node         DB
            Node
            Node       Node
                       Node
Don’t we want to move
    “heavy work”?
Client → Server   Server → DB




         Computation     Computation
Better architecture
Front-end
Client                Database
           Farm

                         DB


User       Node
           Node
            Node
            Node                    Big Slow
                     Logging farm
                                      Disk

                        Node
                        Node          Disk
Move work which isn’t
user-facing out of main
      event loop
Ensure consistency of
  Node processes
Distributing work
Cluster
var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  // Fork workers.
  for (var i = 0; i < numCPUs; i++) {
    cluster.fork();
  }
  cluster.on('death', function(worker) {
    console.log('worker ' + worker.pid + ' died');
  });
} else {
  // Worker processes have a http server.
  http.Server(function(req, res) {
    res.writeHead(200);
    res.end("hello worldn"); }).listen(8000);
}
Use load balancers to
  distribute across
       servers
node-proxy
   squid
  varnish
 haproxy
Unbundle SSL
          stud, stunnel, etc

http://vincent.bernat.im/en/blog/2011-
   ssl-benchmark.html#conclusion
Sharding
Disclaimer:
 Sharding is hard
See CAP theorem
Socket.io
Web Socket library
client and server
with the shared API
var app = require('express').createServer(),
   io = require('socket.io').listen(app);

app.listen(80);

app.get('/', function (req, res) {
  res.sendfile(__dirname + '/index.html');
});

io.sockets.on('connection', function (socket) {
  socket.emit('news', { hello: 'world' });
  socket.on('my other event', function (data) {
    console.log(data);
  });
});
<!DOCTYPE html>
<html>
<body>
<script src="/socket.io/socket.io.js"></script>
<script>
var socket = io.connect('http://localhost');
socket.connect();
socket.on('connect', function(){ console.log('connect') })
socket.on('message', function(){ console.log('message') })
socket.on('disconnect', function(){ console.log('disconnect'); })
</script>
</body>
</html>
Transports
• WebSocket
• Adobe® Flash® Socket
• AJAX long polling
• AJAX multipart streaming
• Forever iframe
• JSONP Polling
options = {
 transports: ['websocket'],
 log: util.log }

io.listen(server, options)
// note, io.listen() will create a http server for you
var io = require('socket.io').listen(80);

io.sockets.on('connection', function (socket) {
  io.sockets.emit('this', { will: 'be received by everyone'});

  socket.on('private message', function (from, msg) {
    console.log('I received a private message by ', from, ' saying ',
msg);
  });

  socket.on('disconnect', function () {
    sockets.emit('user disconnected');
  });
});
Exercises
• Create a socket.io connect to an
  express server
• Create a route which loads a page that
  includes socket.io

• Send "hello world" to the client
  sockets
• Make the client respond with "thanks"
  and disconnect from the server
Using Redis with
   Socket.io
Why use Redis?

• No shared memory
• Cluster on server won’t share client data
• Multiple servers can use the same Redis
var express = require('express')
, app = express.createServer();

var sio = require('socket.io')
, RedisStore = sio.RedisStore
, io = sio.listen(app);

app.listen(8080);

app.get('/', function(req,res) {
  res.sendfile(__dirname + '/index.html');
});

io.sockets.on('connection', function (socket) {
  socket.on('chat', function (data) {
    console.log(data);
    socket.broadcast.emit('chat', data);
  })
});
var cluster = require('cluster');
var http = require('http');
var numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  // Fork workers.
  for (var i = 0; i < numCPUs; i++) {
    cluster.fork();
  }
} else {
  var express = require('express')
  , app = express.createServer();

    var sio = require('socket.io')
    , RedisStore = sio.RedisStore
    , io = sio.listen(app);

    app.listen(8080);

    app.get('/', function(req,res) {
      res.sendfile(__dirname + '/index.html');
    });

    // Somehow pass this information to the workers
    io.set('store', new RedisStore);

    // Do the work here
    io.sockets.on('connection', function (socket) {
      socket.on('chat', function (data) {
        console.log(data);
        socket.broadcast.emit('chat', data);
      })
    });
}
Node in production
Error handling
var http = require('http');

var req = http.request({
   host: 'www.google.com',
   path: '/',
   port: 80,
   method: 'POST'
   }, function (response) {
   // Do stuff with the response here
});
node.js:134
   throw e; // process.nextTick error, or 'error' event on first tick
^ Error: Uncaught, unspecified 'error' event.
at EventEmitter.emit (events.js:47:15) at Object.<anonymous> (/
Users/you/y-u-no-listen-for-errors.js:5:9) at Module._compile
(module.js:404:26) at Object..js (module.js:410:10) at Module.load
(module.js:336:31) at Function._load (module.js:297:12) at
Array.<anonymous> (module.js:423:10) at EventEmitter._tickCallback
(node.js:126:26)
var http = require('http');

try {
  var req = http.request({
     host: 'www.google.com',
     path: '/',
     port: 80,
     method: 'POST'
     }, function (response) {
     // Do stuff with the response here
  });
} catch(e) {
var http = require('http');

var req = http.request({
   host: 'www.google.com',
   path: '/',
   port: 80,
   method: 'POST'
   }, function (response) {
   // Do stuff with the response here
});

req.on('error', function (err) {
  //safely handle this if possible
});
// Suppress errors
process.on('uncaughtException', function (err) {
  // Log it!
  console.dir(err);
});
EventEmitter leaks
(node) warning: possible EventEmitter memory leak detected. 11
listeners added. Use emitter.setMaxListeners() to increase limit. Trace:
  at Pool.<anonymous> (events.js:101:17)
  at Object.proxyRequest (~/http-proxy/lib/node-http-proxy.js:185:7)
  at Server.<anonymous> (/Users/some-user/myapp.js:14:9)
  at Server.emit (events.js:45:17)
  at HTTPParser.onIncoming (http.js:1078:12)
  at HTTPParser.onHeadersComplete (http.js:87:31)
  at Socket.ondata (http.js:977:22)
  at Socket._onReadable (net.js:654:27)
  at IOWatcher.onReadable [as callback] (net.js:156:10)
var events = require('events');

function doSomethingThenTellMe () {
 var emitter = new events.EventEmitter();

 setTimeout(function () {
   emitter.emit('done');
   }, 2000);
   return emitter;
 }

var doingIt = doSomethingThenTellMe();

doingIt.on('done', function () {
  console.log("Ok, it's done");
});
// Why are you using `.on()`?
// You only expect this event to fire once.
once() is awesome
var events = require('events');

function doSomethingThenTellMe () {
 var emitter = new events.EventEmitter();

 setTimeout(function () {
   emitter.emit('done');
   }, 2000);
   return emitter;
 }

var doingIt = doSomethingThenTellMe();

doingIt.once('done', function () {
  console.log("Ok, it's done");
});
Process monitoring
Upstart
description "node.js server"
author    "croucher`"

start on startup
stop on shutdown

script
   # We found $HOME is needed. Without it, we ran into
problems
   export HOME="/root"

  exec /usr/local/bin/node /var/noderoot/index.js 2>&1 >> /
var/log/node.log
end script
forever
$ cd /path/to/your/app
$ forever start bin/yourapp
info: Running action: start
info: Forever processing
file: examples/server.js
$ forever list
info: Running action: list
info: Forever processes running
  [0] bin/yourapp [77041, 77040] /Users/You/.forever
20dL.log 0:0:0:1.788
NPM Packaging
Enki:~/Code/node-dnsserve(master) $ ls
LICENSE
 
 README
 
 dnsserver.js
package.json
Enki:~/Code/node-dnsserve(master) $
{
  "name": "dns-server",
  "description": "DNS server for Node",
  "version": "0.0.1a",
  "author": "Tom Hughes-Croucher
<tom.croucher@gmail.com>",
  "main" : "dnsserver"
}
Enki:~/Code/node-dnsserve(master) $ sudo npm
install . -g
dns-server@0.0.1a /usr/local/lib/node_modules/dns-
server
Enki:~/Code/node-dnsserve(master) $
Enki:~/Code/node-dnsserve(master) $ sudo npm link

/usr/local/lib/node_modules/dns-server -> /Users/sh1mmer/Code/
node-dnsserve
Enki:~/Code/node-dnsserve(master) $ npm ls -g
/usr/local/lib
├── dns-server@0.0.1a -> /Users/sh1mmer/Code/node-dnsserve
└─┬ npm@1.0.6
 ├── abbrev@1.0.3
 ├── node-uuid@1.1.0
 ├── nopt@1.0.4
 └── semver@1.0.5
Enki:~/Code/node-dnsserve(master) $
Enki:~/Code/node-dnsserve(master) $ npm adduser
Username: foobarbaz
Password:
Email:
Enki:~/Code/node-dnsserve(master) $ npm publish
npm WARN Sending authorization over insecure
channel.
Enki:~/Code/node-dnsserve(master) $
{
    "name": "winston",
    "description": "A multi-transport async logging library for Node.js",
    "version": "0.2.7",
    "author": "Charlie Robbins <charlie.robbins@gmail.com>",
    "contributors": [
      { "name": "Matthew Bergman", "email": "mzbphoto@gmail.com" }
    ],
    "repository": {
      "type": "git",
      "url": "http://github.com/indexzero/winston.git"
    },
    "keywords": ["logging", "sysadmin", "tools"],
    "dependencies": {
      "colors": ">= 0.3.0",
      "eyes": ">= 0.1.6",
      "loggly": ">= 0.1.4",
      "vows": ">= 0.5.2"
    },
    "main": "./lib/winston",
    "scripts": { "test": "vows test/*-test.js --spec" },
    "engines": { "node": ">= 0.3.0" }
}
{
    "name": "winston",
    "description": "A multi-transport async logging library for Node.js",
    "version": "0.2.7",
    "author": "Charlie Robbins <charlie.robbins@gmail.com>",
    "contributors": [
      { "name": "Matthew Bergman", "email": "mzbphoto@gmail.com" }
    ],
    "repository": {
      "type": "git",
      "url": "http://github.com/indexzero/winston.git"
    },
    "keywords": ["logging", "sysadmin", "tools"],
    "dependencies": {
      "colors": ">= 0.x.x",
      "eyes": ">= 0.1.x",
      "loggly": ">= 0.1.x",
      "vows": ">= 0.5.x"
    },
    "main": "./lib/winston",
    "scripts": { "test": "vows test/*-test.js --spec" },
    "engines": { "node": ">= 0.3.0" }
}
Questions

tom@jetpacksfordinosaurs.com
         @sh1mmer

More Related Content

PDF
Building servers with Node.js
KEY
node.js: Javascript's in your backend
PPTX
introduction to node.js
PDF
Node.js and How JavaScript is Changing Server Programming
KEY
A million connections and beyond - Node.js at scale
KEY
NodeJS
PDF
Server Side Event Driven Programming
PDF
Nodejs Explained with Examples
Building servers with Node.js
node.js: Javascript's in your backend
introduction to node.js
Node.js and How JavaScript is Changing Server Programming
A million connections and beyond - Node.js at scale
NodeJS
Server Side Event Driven Programming
Nodejs Explained with Examples

What's hot (20)

KEY
OSCON 2011 - Node.js Tutorial
PPTX
Java script at backend nodejs
PPT
RESTful API In Node Js using Express
PPTX
Introduction Node.js
PDF
NodeJS
PPT
Node js presentation
PPT
Building your first Node app with Connect & Express
PDF
NodeJS for Beginner
PDF
Node.js - A Quick Tour
PDF
Node.js Explained
PDF
Non-blocking I/O, Event loops and node.js
PDF
Original slides from Ryan Dahl's NodeJs intro talk
PDF
Nodejs in Production
PDF
All aboard the NodeJS Express
PPT
Nodejs Event Driven Concurrency for Web Applications
PDF
Getting started with developing Nodejs
KEY
Building a real life application in node js
PPTX
Intro to Node.js (v1)
PDF
Node Architecture and Getting Started with Express
KEY
Introduction to node.js
OSCON 2011 - Node.js Tutorial
Java script at backend nodejs
RESTful API In Node Js using Express
Introduction Node.js
NodeJS
Node js presentation
Building your first Node app with Connect & Express
NodeJS for Beginner
Node.js - A Quick Tour
Node.js Explained
Non-blocking I/O, Event loops and node.js
Original slides from Ryan Dahl's NodeJs intro talk
Nodejs in Production
All aboard the NodeJS Express
Nodejs Event Driven Concurrency for Web Applications
Getting started with developing Nodejs
Building a real life application in node js
Intro to Node.js (v1)
Node Architecture and Getting Started with Express
Introduction to node.js
Ad

Viewers also liked (20)

KEY
Node.js - Best practices
PDF
Introduction to Nodejs
PDF
Modern UI Development With Node.js
PPTX
Introduction to Node.js
PDF
Native Desktop App with Node.js Webkit (HTML, CSS & Javascript)
PDF
Introduction to Node.js: perspectives from a Drupal dev
PPTX
Angular 2.0: Getting ready
PDF
Grunt JS - Getting Started With Grunt
PPTX
Grunt - The JavaScript Task Runner
PPTX
Node.js Patterns for Discerning Developers
PDF
(C)NodeJS
KEY
Node.js ― Hello, world! の1歩先へ。
PDF
Codemotion rome 2015 bluemix lab tutorial -- Codemotion Rome 2015
PDF
Luciano Fiandesio - Docker 101 | Codemotion Milan 2015
ODP
Scaling and securing node.js apps
PDF
Building web apps with node.js, socket.io, knockout.js and zombie.js - Codemo...
PDF
An introduction to workflow-based programming with Node-RED
ODP
Node.js security
PDF
Flow Base Programming with Node-RED and Functional Reactive Programming with ...
PDF
Come rendere il proprio prodotto una bomba creandogli una intera community in...
Node.js - Best practices
Introduction to Nodejs
Modern UI Development With Node.js
Introduction to Node.js
Native Desktop App with Node.js Webkit (HTML, CSS & Javascript)
Introduction to Node.js: perspectives from a Drupal dev
Angular 2.0: Getting ready
Grunt JS - Getting Started With Grunt
Grunt - The JavaScript Task Runner
Node.js Patterns for Discerning Developers
(C)NodeJS
Node.js ― Hello, world! の1歩先へ。
Codemotion rome 2015 bluemix lab tutorial -- Codemotion Rome 2015
Luciano Fiandesio - Docker 101 | Codemotion Milan 2015
Scaling and securing node.js apps
Building web apps with node.js, socket.io, knockout.js and zombie.js - Codemo...
An introduction to workflow-based programming with Node-RED
Node.js security
Flow Base Programming with Node-RED and Functional Reactive Programming with ...
Come rendere il proprio prodotto una bomba creandogli una intera community in...
Ad

Similar to Writing robust Node.js applications (20)

PPTX
Building and Scaling Node.js Applications
PDF
Node.js - async for the rest of us.
PDF
Nodejs - A quick tour (v6)
KEY
Practical Use of MongoDB for Node.js
PDF
Introduction to Node.js
KEY
Playing With Fire - An Introduction to Node.js
KEY
Node.js - The New, New Hotness
PPTX
KEY
A language for the Internet: Why JavaScript and Node.js is right for Internet...
ODP
Introduce about Nodejs - duyetdev.com
PDF
Nodejs - A quick tour (v5)
PDF
Developing realtime apps with Drupal and NodeJS
KEY
A language for the Internet: Why JavaScript and Node.js is right for Internet...
PPTX
An overview of node.js
PDF
soft-shake.ch - Hands on Node.js
PDF
Introduction to Node.js: What, why and how?
KEY
Node.js - A practical introduction (v2)
PPTX
A slightly advanced introduction to node.js
PPTX
Scalable network applications, event-driven - Node JS
PDF
JavaScript is the new black - Why Node.js is going to rock your world - Web 2...
Building and Scaling Node.js Applications
Node.js - async for the rest of us.
Nodejs - A quick tour (v6)
Practical Use of MongoDB for Node.js
Introduction to Node.js
Playing With Fire - An Introduction to Node.js
Node.js - The New, New Hotness
A language for the Internet: Why JavaScript and Node.js is right for Internet...
Introduce about Nodejs - duyetdev.com
Nodejs - A quick tour (v5)
Developing realtime apps with Drupal and NodeJS
A language for the Internet: Why JavaScript and Node.js is right for Internet...
An overview of node.js
soft-shake.ch - Hands on Node.js
Introduction to Node.js: What, why and how?
Node.js - A practical introduction (v2)
A slightly advanced introduction to node.js
Scalable network applications, event-driven - Node JS
JavaScript is the new black - Why Node.js is going to rock your world - Web 2...

More from Tom Croucher (20)

PDF
Using Node.js to Build Great Streaming Services - HTML5 Dev Conf
KEY
Streams are Awesome - (Node.js) TimesOpen Sep 2012
KEY
Using Node.js to improve the performance of Mobile apps and Mobile web
KEY
Creating the Internet of Things with JavaScript - Fluent Conf
KEY
Using Node.js to make HTML5 work for everyone
PDF
Lessons from a coding veteran - Web Directions @Media
KEY
Multi-tiered Node Architectures - JSConf 2011
PDF
How to stop writing spaghetti code
PDF
Doing Horrible Things with DNS - Web Directions South
PDF
Doing Horrible Things to DNS in the Name of Science - SF Performance Meetup
KEY
How to stop writing spaghetti code - JSConf.eu 2010
PDF
Sf perf
PDF
Server Side JavaScript - You ain't seen nothing yet
PDF
JavaScript Everywhere! Creating a 100% JavaScript web stack
PDF
Mobile Data: How to avoid the latency trap - SWDC 2010
KEY
Let's run JavaScript Everywhere
KEY
Pirate yql
KEY
YQL Tutorial
PPT
How to avoid the latency trap and lessons about software design
PPT
Unicorns Metrics and Hotsauce - Lessons about Evangelism from the Yahoo! Deve...
Using Node.js to Build Great Streaming Services - HTML5 Dev Conf
Streams are Awesome - (Node.js) TimesOpen Sep 2012
Using Node.js to improve the performance of Mobile apps and Mobile web
Creating the Internet of Things with JavaScript - Fluent Conf
Using Node.js to make HTML5 work for everyone
Lessons from a coding veteran - Web Directions @Media
Multi-tiered Node Architectures - JSConf 2011
How to stop writing spaghetti code
Doing Horrible Things with DNS - Web Directions South
Doing Horrible Things to DNS in the Name of Science - SF Performance Meetup
How to stop writing spaghetti code - JSConf.eu 2010
Sf perf
Server Side JavaScript - You ain't seen nothing yet
JavaScript Everywhere! Creating a 100% JavaScript web stack
Mobile Data: How to avoid the latency trap - SWDC 2010
Let's run JavaScript Everywhere
Pirate yql
YQL Tutorial
How to avoid the latency trap and lessons about software design
Unicorns Metrics and Hotsauce - Lessons about Evangelism from the Yahoo! Deve...

Recently uploaded (20)

PPTX
Programs and apps: productivity, graphics, security and other tools
PDF
A comparative analysis of optical character recognition models for extracting...
PDF
Accuracy of neural networks in brain wave diagnosis of schizophrenia
PDF
Machine learning based COVID-19 study performance prediction
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PPT
Teaching material agriculture food technology
PDF
Assigned Numbers - 2025 - Bluetooth® Document
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PDF
Network Security Unit 5.pdf for BCA BBA.
PPTX
Machine Learning_overview_presentation.pptx
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PPTX
SOPHOS-XG Firewall Administrator PPT.pptx
PPTX
Big Data Technologies - Introduction.pptx
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PDF
NewMind AI Weekly Chronicles - August'25-Week II
PDF
Approach and Philosophy of On baking technology
PDF
Diabetes mellitus diagnosis method based random forest with bat algorithm
Programs and apps: productivity, graphics, security and other tools
A comparative analysis of optical character recognition models for extracting...
Accuracy of neural networks in brain wave diagnosis of schizophrenia
Machine learning based COVID-19 study performance prediction
The Rise and Fall of 3GPP – Time for a Sabbatical?
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Teaching material agriculture food technology
Assigned Numbers - 2025 - Bluetooth® Document
“AI and Expert System Decision Support & Business Intelligence Systems”
Network Security Unit 5.pdf for BCA BBA.
Machine Learning_overview_presentation.pptx
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
SOPHOS-XG Firewall Administrator PPT.pptx
Big Data Technologies - Introduction.pptx
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
Building Integrated photovoltaic BIPV_UPV.pdf
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
NewMind AI Weekly Chronicles - August'25-Week II
Approach and Philosophy of On baking technology
Diabetes mellitus diagnosis method based random forest with bat algorithm

Writing robust Node.js applications

  • 1. Node.js Tutorial Tom Hughes-Croucher, Principal Jetpacks For Dinosaurs, LLC [email protected] @sh1mmer
  • 2. Introduction • Tom Hughes-Croucher • Principal at Jetpacks for Dinosaurs • Node.js and High-performance web site consulting and training • Walmart, MySpace, Joyent,Yahoo!, NASA, Tesco, etc • Node.js contributor • Lead author of "Node: Up and Running"
  • 3. Scalable Server-Side Code with JavaScript Node Up and Running Tom Hughes-Croucher http://ofps.oreilly.com/titles/9781449398583/ http://shop.oreilly.com/product/0636920015956.do
  • 4. Training Online In person
  • 8. Enki:~/Code/node-examples $ node --debug helloworld.js debugger listening on port 5858 Server running at http://127.0.0.1:8124/
  • 9. enki:~ sh1mmer$ ps -A | grep node 19093 ttys001 0:00.39 node index.js 19273 ttys002 0:00.00 grep node enki:~ sh1mmer$ kill -s USR1 19093
  • 10. enki:~ sh1mmer$ node index.js Hit SIGUSR1 - starting debugger agent. debugger listening on port 5858
  • 11. Enki:~ $ sudo npm install -g node-inspector [email protected] ./node_modules/node-inspector ├── [email protected] └── [email protected] Enki:~ $ node-inspector visit http://0.0.0.0:8080/debug?port=5858 to start debugging
  • 13. Exercises • Modify a basic HTTP server to return the text "I'm learning Node" • Change the HTTP response to HTML and return your text in an HTML page • Return the User-Agent string from the browser as part of your HTML page
  • 15. Sinatra Style MVC framework
  • 16. var app = require('express').createServer(); app.get('/', function(req, res){ res.send('hello world'); }); app.listen(3000);
  • 19. app.use(express.bodyParser()); app.use(express.cookieParser()); app.post('/', function(req, res){ // Perhaps we posted several items with a form // (use the bodyParser() middleware for this) var items = req.body.items; console.log(items); res.send('logging'); });
  • 21. var express = require("express"); app.configure(function () { var public = __dirname + "/../public/"; public = require("path").normalize(public); app.set("views", __dirname + "/views"); app.set("view engine", "jade"); }); app.get("/", function (req, res) { res.render("index", { locals : { h1: 'Router Stats', scripts : [ "/public/smoothie.js", "/public/raphael.js", "/public/base.js", "/public/gfx.js", "/public/explore.js", "/public/app.js" ] } } });
  • 22. Exercise • Create an Express server • Make routes for ‘/’ & ‘/products’ • Serve two different pages based on value of the query string parameter "page" • Create a redirect from /old to /new • Set a cookie on the client
  • 23. Building a chat server
  • 26. Client Front-end Database User Node DB
  • 28. Heavy Front-end Client Processor Database Farm Work User Node Node Node Node DB Node Node Node Node
  • 29. Don’t we want to move “heavy work”?
  • 30. Client → Server Server → DB Computation Computation
  • 32. Front-end Client Database Farm DB User Node Node Node Node Big Slow Logging farm Disk Node Node Disk
  • 33. Move work which isn’t user-facing out of main event loop
  • 34. Ensure consistency of Node processes
  • 37. var cluster = require('cluster'); var http = require('http'); var numCPUs = require('os').cpus().length; if (cluster.isMaster) { // Fork workers. for (var i = 0; i < numCPUs; i++) { cluster.fork(); } cluster.on('death', function(worker) { console.log('worker ' + worker.pid + ' died'); }); } else { // Worker processes have a http server. http.Server(function(req, res) { res.writeHead(200); res.end("hello worldn"); }).listen(8000); }
  • 38. Use load balancers to distribute across servers
  • 39. node-proxy squid varnish haproxy
  • 40. Unbundle SSL stud, stunnel, etc http://vincent.bernat.im/en/blog/2011- ssl-benchmark.html#conclusion
  • 42. Disclaimer: Sharding is hard See CAP theorem
  • 45. client and server with the shared API
  • 46. var app = require('express').createServer(), io = require('socket.io').listen(app); app.listen(80); app.get('/', function (req, res) {   res.sendfile(__dirname + '/index.html'); }); io.sockets.on('connection', function (socket) {   socket.emit('news', { hello: 'world' });   socket.on('my other event', function (data) {     console.log(data);   }); });
  • 47. <!DOCTYPE html> <html> <body> <script src="/socket.io/socket.io.js"></script> <script> var socket = io.connect('http://localhost'); socket.connect(); socket.on('connect', function(){ console.log('connect') }) socket.on('message', function(){ console.log('message') }) socket.on('disconnect', function(){ console.log('disconnect'); }) </script> </body> </html>
  • 48. Transports • WebSocket • Adobe® Flash® Socket • AJAX long polling • AJAX multipart streaming • Forever iframe • JSONP Polling
  • 49. options = { transports: ['websocket'], log: util.log } io.listen(server, options)
  • 50. // note, io.listen() will create a http server for you var io = require('socket.io').listen(80); io.sockets.on('connection', function (socket) {   io.sockets.emit('this', { will: 'be received by everyone'});   socket.on('private message', function (from, msg) {     console.log('I received a private message by ', from, ' saying ', msg);   });   socket.on('disconnect', function () {     sockets.emit('user disconnected');   }); });
  • 51. Exercises • Create a socket.io connect to an express server • Create a route which loads a page that includes socket.io • Send "hello world" to the client sockets • Make the client respond with "thanks" and disconnect from the server
  • 52. Using Redis with Socket.io
  • 53. Why use Redis? • No shared memory • Cluster on server won’t share client data • Multiple servers can use the same Redis
  • 54. var express = require('express') , app = express.createServer(); var sio = require('socket.io') , RedisStore = sio.RedisStore , io = sio.listen(app); app.listen(8080); app.get('/', function(req,res) { res.sendfile(__dirname + '/index.html'); }); io.sockets.on('connection', function (socket) { socket.on('chat', function (data) { console.log(data); socket.broadcast.emit('chat', data); }) });
  • 55. var cluster = require('cluster'); var http = require('http'); var numCPUs = require('os').cpus().length; if (cluster.isMaster) { // Fork workers. for (var i = 0; i < numCPUs; i++) { cluster.fork(); } } else { var express = require('express') , app = express.createServer(); var sio = require('socket.io') , RedisStore = sio.RedisStore , io = sio.listen(app); app.listen(8080); app.get('/', function(req,res) { res.sendfile(__dirname + '/index.html'); }); // Somehow pass this information to the workers io.set('store', new RedisStore); // Do the work here io.sockets.on('connection', function (socket) { socket.on('chat', function (data) { console.log(data); socket.broadcast.emit('chat', data); }) }); }
  • 58. var http = require('http'); var req = http.request({ host: 'www.google.com', path: '/', port: 80, method: 'POST' }, function (response) { // Do stuff with the response here });
  • 59. node.js:134 throw e; // process.nextTick error, or 'error' event on first tick ^ Error: Uncaught, unspecified 'error' event. at EventEmitter.emit (events.js:47:15) at Object.<anonymous> (/ Users/you/y-u-no-listen-for-errors.js:5:9) at Module._compile (module.js:404:26) at Object..js (module.js:410:10) at Module.load (module.js:336:31) at Function._load (module.js:297:12) at Array.<anonymous> (module.js:423:10) at EventEmitter._tickCallback (node.js:126:26)
  • 60. var http = require('http'); try { var req = http.request({ host: 'www.google.com', path: '/', port: 80, method: 'POST' }, function (response) { // Do stuff with the response here }); } catch(e) {
  • 61. var http = require('http'); var req = http.request({ host: 'www.google.com', path: '/', port: 80, method: 'POST' }, function (response) { // Do stuff with the response here }); req.on('error', function (err) { //safely handle this if possible });
  • 62. // Suppress errors process.on('uncaughtException', function (err) { // Log it! console.dir(err); });
  • 64. (node) warning: possible EventEmitter memory leak detected. 11 listeners added. Use emitter.setMaxListeners() to increase limit. Trace: at Pool.<anonymous> (events.js:101:17) at Object.proxyRequest (~/http-proxy/lib/node-http-proxy.js:185:7) at Server.<anonymous> (/Users/some-user/myapp.js:14:9) at Server.emit (events.js:45:17) at HTTPParser.onIncoming (http.js:1078:12) at HTTPParser.onHeadersComplete (http.js:87:31) at Socket.ondata (http.js:977:22) at Socket._onReadable (net.js:654:27) at IOWatcher.onReadable [as callback] (net.js:156:10)
  • 65. var events = require('events'); function doSomethingThenTellMe () { var emitter = new events.EventEmitter(); setTimeout(function () { emitter.emit('done'); }, 2000); return emitter; } var doingIt = doSomethingThenTellMe(); doingIt.on('done', function () { console.log("Ok, it's done"); }); // Why are you using `.on()`? // You only expect this event to fire once.
  • 67. var events = require('events'); function doSomethingThenTellMe () { var emitter = new events.EventEmitter(); setTimeout(function () { emitter.emit('done'); }, 2000); return emitter; } var doingIt = doSomethingThenTellMe(); doingIt.once('done', function () { console.log("Ok, it's done"); });
  • 70. description "node.js server" author "croucher`" start on startup stop on shutdown script # We found $HOME is needed. Without it, we ran into problems export HOME="/root" exec /usr/local/bin/node /var/noderoot/index.js 2>&1 >> / var/log/node.log end script
  • 72. $ cd /path/to/your/app $ forever start bin/yourapp info: Running action: start info: Forever processing file: examples/server.js $ forever list info: Running action: list info: Forever processes running [0] bin/yourapp [77041, 77040] /Users/You/.forever 20dL.log 0:0:0:1.788
  • 74. Enki:~/Code/node-dnsserve(master) $ ls LICENSE README dnsserver.js package.json Enki:~/Code/node-dnsserve(master) $
  • 75. { "name": "dns-server", "description": "DNS server for Node", "version": "0.0.1a", "author": "Tom Hughes-Croucher <[email protected]>", "main" : "dnsserver" }
  • 76. Enki:~/Code/node-dnsserve(master) $ sudo npm install . -g [email protected] /usr/local/lib/node_modules/dns- server Enki:~/Code/node-dnsserve(master) $
  • 77. Enki:~/Code/node-dnsserve(master) $ sudo npm link /usr/local/lib/node_modules/dns-server -> /Users/sh1mmer/Code/ node-dnsserve Enki:~/Code/node-dnsserve(master) $ npm ls -g /usr/local/lib ├── [email protected] -> /Users/sh1mmer/Code/node-dnsserve └─┬ [email protected] ├── [email protected] ├── [email protected] ├── [email protected] └── [email protected] Enki:~/Code/node-dnsserve(master) $
  • 78. Enki:~/Code/node-dnsserve(master) $ npm adduser Username: foobarbaz Password: Email:
  • 79. Enki:~/Code/node-dnsserve(master) $ npm publish npm WARN Sending authorization over insecure channel. Enki:~/Code/node-dnsserve(master) $
  • 80. { "name": "winston", "description": "A multi-transport async logging library for Node.js", "version": "0.2.7", "author": "Charlie Robbins <[email protected]>", "contributors": [ { "name": "Matthew Bergman", "email": "[email protected]" } ], "repository": { "type": "git", "url": "http://github.com/indexzero/winston.git" }, "keywords": ["logging", "sysadmin", "tools"], "dependencies": { "colors": ">= 0.3.0", "eyes": ">= 0.1.6", "loggly": ">= 0.1.4", "vows": ">= 0.5.2" }, "main": "./lib/winston", "scripts": { "test": "vows test/*-test.js --spec" }, "engines": { "node": ">= 0.3.0" } }
  • 81. { "name": "winston", "description": "A multi-transport async logging library for Node.js", "version": "0.2.7", "author": "Charlie Robbins <[email protected]>", "contributors": [ { "name": "Matthew Bergman", "email": "[email protected]" } ], "repository": { "type": "git", "url": "http://github.com/indexzero/winston.git" }, "keywords": ["logging", "sysadmin", "tools"], "dependencies": { "colors": ">= 0.x.x", "eyes": ">= 0.1.x", "loggly": ">= 0.1.x", "vows": ">= 0.5.x" }, "main": "./lib/winston", "scripts": { "test": "vows test/*-test.js --spec" }, "engines": { "node": ">= 0.3.0" } }

Editor's Notes