Introduction To Nodejs
Introduction To Nodejs
Agenda
1. About Node.js Internal working of Node.js Buzz around Node.js Who is using it What kind of apps are being built Coding in Node.js Sync v/s Async coding (Callbacks) Classes & Modules (CommonJS) npm & package.json Node.js EventEmitters
2.
What is Node.js
Node.js is a platform to build fast and scalable network applications. It is built on Google Chromes v8 engine & implements event-driven, nonblocking I/O model. It is ~80% C/C++ & ~20% JS (APIs) Uses CommonJS module system. Executes JavaScript on the server Built by Ryan Dahl Sponsored by Joyent
What is Node.js
Biggest thing Node.js brings to the table (other than JS, of course) is savings in I/O cost
http://blog.mixu.net/2011/02/01/understanding-the-node-js-event-loop/
Node.js saves I/O cost by implementing event driven, Non-blocking I/O model
What exactly is a event-driven, non-blocking server? How is it different from a multi-threaded server?
User1
i/o request
T1 DB T2 Blocking I/O
User2
i/o request
T3
T4 T5
FS
T6
T7 T8
T9
User1
i/o request
T1 V8
DB
User2
i/o request
T1 V8
Non-blocking I/O
FS
T1 V8
Node.js
t1 t3
10
t2
11
At ~4000 concurrent connections, - Nginx can serve ~9000 reqs/sec - Apache can serve ~3000 reqs/sec
Ref: http://blog.webfaction.com/a-little-holiday-present
12
At ~4000 concurrent connections, - Nginx uses 3MB memory - Apache uses 40MB memory
Ref: http://blog.webfaction.com/a-little-holiday-present
13
14
15
https://github.com/joyent/node/wiki/modules
16
17
Agenda part 2
1. About Node.js Internal working of Node.js Buzz around Node.js Who is using it What kind of apps are being built Coding in Node.js Sync v/s Async coding (Callbacks) Classes & Modules (CommonJS) npm & package.json Node.js EventEmitters
2.
18
19
Things to note: 1. Async code doesnt directly return anything 2. Instead, it takes a function(callback) & calls that function when result becomes available
20
//step 5 V8 is free to run other functions in the eventloop. //step 5, step 6 ..step 100 Say v8 notices 95 other things to do (in the event loop), it starts executing them one by one. At some point b/w step 3 and step 100, returns result & asks to run dbConnection.writes callback. This event goes to the back of the queue as step 101
Node.js Programming
22
23
CommonJS modules
//Automobile.js file function Automobile(license, model) { this.license = license; this.model = model; } Automobile.prototype.getModel = function() { return model; } exports.Automobile = Automobile;
Things to note: 1. Allows keeping JS code in separate files 2. Use exports.<name> to export something 1. Use require(path/to/module) to import it 2. use require(module).<name> to access things inside module
//Car.js file var util = require('util'); var module = require('./Automobile'); var Automobile = module.Automobile;
function Car(license, model) { Automobile.call(this, license, model); } util.inherits(Car, Automobile); console.log(new Car("1232", "BMW").model); //prints BMW
24
Things to note: 1. You can directly export function, arrays, variables 2. You can export multiple things from one file using exports
//app.js file var myModule = require('./myModule'); console.log(myModule.myFunction()); //prints hi there console.log(myModule.myArray[1]); //prints bar console.log(myModule.myVariable); //prints Im a variable
25
Things to note: If you want to export only one class/function.. so that it can be used directly by the recipient, you can use: module.exports = <something>; Warning: If you use both module.exports and exports.bla, exports.bla will NOT be exported(ignored)
26
Things to note: 1. npm = Node Package Manager 2. It is a CLI to install modules from http://search.npmjs.org 3. LOCAL: npm install express 1. It installs in myapp/node_modules/express 4. GLOBAL: npm install express -g 1. It installs in /usr/local/lib/node_modules/ (default) 2. Installs executable files in /usr/local/.bin (default) 5. Use GLOBAL when the library has some shell script & want to reuse it for different apps
27
28
EventEmitter class implements Observer pattern and provides on and emit APIs - It is used when creating (not using) an async library.
Node.js EventEmitter
29
//Simplified EventEmitter (Observer pattern) function EventEmitter() { //store events and callbacks like {event1: [callback1, callback2] , event2 : [cb3, cb4]} this.eventNameAndCallbackList = {}; } //Allow others to add a callback(function) for a event name(string) EventEmitter.prototype.on = function(eventName, callback) { //add eventName and callback to eventNameAndCallbackList }; //When an event is emitted, call each callbacks in a loop EventEmitter.prototype.emit = function(eventName) { for(var i =0; i < currentCallbacks.length ; i++) { currentCallbacks[i](); //call each callback } }; exports.EventEmitter = EventEmitter;
30
//app.js var myIOModule = require('./myIOModule'); var myIOClass = new myIOModule.MyIOClass(); myIOClass.on('data', function (data) { console.log(data); }); myIOClass.readFromDB('select * from users');
32
db.connect(127.0.0.1, 100);
}
33
//Say there was an exception trying to connect to db. Function () { //Typically I/O libraries triggers error event (or callback). Well need to listen to that event db.on(error, function(e) { console.error(e); }); db.connect(127.0.0.1, 100); // failed to connect; connectionException }
34
ExpressJS
35
Things to note:
1. ExpressJS is Ruby Sinatra inspired web framework 2. It is built on top of Connect which itself is a wrapper for http-module 3. It provides support for: 1. Dev/Prod Configurations 2. Routes 3. Templating 4. Sessions 5. Many, many other features
app.listen(port, host);
36
//Middlewares app.use(express.logger()); //logs requests app.use(express.static(__dirname + /public)); //sets location of public files app.use(express.bodyParser()); //parses HTTP POST body
Things to Note: 1. Middlewares are functions that helps in common tasks involved building in web applications 2. They are actually connect-module functions but exposed by ExpressJS for simplicity
37
app.configure('development', function() { //On error, print exceptions to console & to the web-page itself app.use(express.errorHandler({ dumpExceptions: true, showStack: true })); });
app.configure('production', function() { //On error, this simply says Internal error Occurred app.use(express.errorHandler({ dumpExceptions: true, showStack: false })); app.use(express.logger()); //logs requests });
Things to Note: 1. Express uses NODE_ENV environment variable to set working environment 2. On CF, to toggle b/w development and production, you can use.. vmc env-add <appName> NODE_ENV production
38
Things to note:
1. You can use Routing to listen to requests to call different functions 2. You can listen to HTTP POST, PUT etc.
39
//Middlewares app.use(express.static(__dirname + /public)); //sets location of public files app.use(express.bodyParser()); //parses HTTP POST body app.use(express.cookieParser()); //Parses cookies headers app.use(express.session({secret: 'your secret here}));
Things to note:
1. To create sessions, use cookieParser & session middlewares 2. By default Express uses MemoryStore to store sessions
40
//Middlewares app.use(express.static(__dirname + /public)); //sets location of public files app.use(express.bodyParser()); //parses HTTP POST body app.use(express.cookieParser()); //Parses cookies headers app.use(express.session({secret: 'your secret here, key: jsessionid }));
Things to note:
1. Sticky Session is a reverse proxy / load balancer feature to help persistent connection 2. When Sticky Session is on, request goes from Nginx to the same instance no matter how many instances of your app is running . 3. Cloud Foundrys Nginx provides Sticky Sessions on jsessionid cookie
4. W/o setting this requests are randomly sent to different instances & youll have to use external store like Redis to fetch session data (recommended).
41
ExpressJS (demo)
42
43
Socket.io
Socket.io
44
Things to Note: 1. Socket.io is mainly used to build real-time apps 2. Socket.io provides a single interface to switch b/w various transport techniques like xhrpolling, websocket, JSONP etc In addition, it provides heartbeats, reconnection, timeouts etc. that are vital for real-time apps. It works seamlessly with ExpressJS
3. 4.
45
46
// Whenever the server emits 'updatechat', this updates the chat body socket.on('updatechat', function (data) { $('#conversation').append(data); // append it to my list });
//When the user enter some data, send it to server function sendchat() { var message = $('#chatField').val(); // Emit or tell server to execute 'sendchat socket.emit('sendchat', message); }
47
48
Questions?
Questions?
@rajaraodv (github.com/rajaraodv) @cloudfoundry (github.com/cloudfoundry)
49