You are on page 1of 30

Server side Javascript environment

What is node.js?
Node.js is a server-side JavaScript environment that uses an asynchronous event-driven model and designed for writing scalable internet applications, notably web servers. This allows Node.js to get excellent performance based on the architectures of many Internet applications. Programs are written in JavaScript, using event-driven, asynchronous I/O to minimize overhead and maximize scalability. Node.js is being hailed as the new Ruby on Rails by some in the developer community. But its not a magic bullet, nor is it appropriate for all programming scenarios.

Why another server side technology?


JavaScript has traditionally only run in the web browser, but recently there has been considerable interest in bringing it to the server side as well, thanks to the CommonJS project. Other server-side JavaScript environments include Jaxer and Narwhal. However, Node.js is a bit different from these solutions, because it is event-based rather than thread based. Web servers like Apache that are used to serve PHP and other CGI scripts are thread based because they spawn a system thread for every incoming request. While this is fine for many applications, the thread based model does not scale well with many long-lived connections like you would need in order to serve real-time applications like Friendfeed or Google Wave.

Why another server side technology?


Node.js, uses an event loop instead of threads, and is able to scale to millions of concurrent connections. It takes advantage of the fact that servers spend most of their time waiting for I/O operations, like reading a file from a hard drive, accessing an external web service or waiting for a file to finish being uploaded, because these operations are much slower than in memory operations. Every I/O operation in Node.js is asynchronous, meaning that the server can continue to process incoming requests while the I/O operation is taking place. JavaScript is extremely well suited to event-based programming because it has anonymous functions and closures which make defining inline callbacks a cinch, and JavaScript developers already know how to program in this way. This event-based model makes Node.js very fast, and makes scaling real-time applications very easy.

Why another server side technology?


Most of the time OS threads wait till some I/O operation finish:

var result = query("select * from users"); for(user in result){ //You get the idea }

In this case the OS thread just sits and waits the I/O operation returns to resume the flow.

Every OS thread takes some memory, so regular servers can't handle many simultaneous connections without penalizing the system performance.

node.js carachteristics
Implemented on top of the V8 js engine (Chromium and Google Chrome engine). Programs are written in plain old javascript, we use the same language for client and server (Die Ruby Die!) Does I/O better:
query("select * from users", function(data, status){ //Do something really cool with users });

Files I/O and db queries are non-blocking Great performance even handling a big number of users It gets better every time google improves V8 It has his own package manager called npm (node package manager)

node.js carachteristics

Nodes Goal
Its goal is to offer an easy and safe way to build high performance and scalable network applications in JavaScript. Those goals are achieved thanks it's architecture:

Single Threaded :
Node use a single thread to run instead of other server like Apache HTTP who spawn a thread per request, this approach result in avoiding CPU context switching and massive execution stacks in memory. This is also the method used by nginx and other servers developed to counter the C10K problem.

Event Loop :
Written in C++ using the Marc Lehmans libev library, the event loop use epoll or kqueue for scalable event notification mechanism.

Non blocking I/O :


Node avoid CPU time loss usually made by waiting for an input or an output response (database, file system, web service, ...) thanks to the full-featured asynchronous I/O provided by Marc Lehmanns libeio library.

Nodes Goal
Node has a built-in support for most important protocols like TCP, DNS, and HTTP (the one that we will focus on). The design goal of a Node application is that any function performing an I/O must use a callback. Thats why there is no blocking methods provided in Nodes API. The HTTP implementation offered by Node is very complete and natively support chunked request and response (very useful since we are going to use the twitter streaming api) and hanging request for comet applications. The Nodes footprint for each http stream is only 36 bytes (source).

Alternatives
Ruby Event Machine Python Twisted

Event driven programming analogy


The Doctors Office Reception Line Analogy
If we relate event-driven programming to standing in the line at a doctors office to see the receptionist. Inevitably, at least in the USA, there are additional forms to fill out with insurance info, privacy releases, etc.

Event driven programming analogy


A Traditional Model
In a traditional thread-based system, when you get to the receptionist you stand at the counter for as long as it takes you to complete your transaction. If you have to fill out 3 forms, you would do so right there at the counter while the receptionist just sits there waiting for you. You are blocking her or him from servicing any other customers.
The only real way to scale a thread-based system is to add more receptionists. This, however, has financial implications in that you have to pay more people and physical implications in that you have to make the room for the additional receptionist windows.

Event driven programming analogy


Events To The Rescue
In an event-based system, when you get to the window and find out you had to complete additional forms, the receptionist gives you the forms, a clipboard and a pen and tells you to come back when you have completed the forms. You go sit down in the waiting and the receptionist helps the next person in line. You are not blocking her from servicing others. When you are done with your forms, you get back in line and wait to speak with the receptionist again. If you have done something incorrectly or need to fill out another form, he or she will give you the new form or tell you the correction and youll repeat the process of going off, doing your work, and then waiting in line again. This system is already highly scalable (and is in fact used in most doctors offices I visit). If the waiting line starts getting too long, you can certainly add an additional receptionist, but you dont need to do so at quite the rate of a thread-based system.

How node works?


The traditional mode of web servers has always been one of the thread-based model. You launch Apache or any other web server and it starts receiving connections. When it receives a connection, it holds that connection open until it has performed the request for the page or whatever other transaction was sent. If it make take a few microseconds to retrieve a page from disk or write results to a database, the web server is blocking on that input/output operation. (This is referred to as blocking I/O.) To scale this type of web server, you need to launch additional copies of the server (referred to as threadbased because each copy typically requires another operating system thread). In contrast, Node.js uses an event-driven model where the web server accepts the request, spins it off to be handled, and then goes on to service the next web request. When the original request is completed, it gets back in the processing queue and when it reaches the front of the queue the results are sent back (or whatever the next action is). This model is highly efficient and scalable because the web server is basically always accepting requests because its not waiting for any read or write operations. (This is referred to as non-blocking I/O or event-driven I/O.) To put it a bit more concretely, consider this process:

How node works?


You use your web browser to make a request for /about.html on a Node.js web server. The Node server accepts your request and calls a function to retrieve that file from disk. While the Node server is waiting for the file to be retrieved, it services the next web request. When the file is retrieved, there is a callback function that is inserted in the Node servers queue. The Node server executes that function which in this case would render the /about.html page and send it back to your web browser. Now, sure, in this case, it may only take microseconds for the server to retrieve the file, but.. microseconds matter!

Particularly when you are talking about highly-scalable web servers! This is what makes Node.js different and of such interest right now. Add in the fact that it also uses the very common language of JavaScript, and it is a very easy way for developers to create very fast and very scalable servers.

What makes Node different?


The common wisdom among many developers is that there is no single right language or framework that should and must be used for all web apps. But based on what we heard from these startups, Node is increasingly being seen as a best solution for a certain type of application. According to Tom Hughes-Croucher, a recent Joyent hire who is writing the first OReilly book on Node, Node has popularized event-driven programming. With event-driven programming, Hughes-Croucher explains, The actual amount of resources you use is much smaller, and you can get a lot more out of fewer servers. Node is all about making event-driven, low-latency, concurrent apps. Erlang, the language that powers Facebooks chat server, uses the same model. Tornado, a concurrent server for Python that powers FriendFeed, was an attempt at this, too. But Node has one advantage over technologies like Erlang and Tornado: None of that was too accessible, says Hughes-Croucher. Node takes a language people know very well Javascript and makes it available to do server programming, as well. In traditional languages and frameworks, the communication inside the app between the web server and the database is the most time-intensive part of the transaction. Node makes a much smaller footprint on your web server. It allocates web server resources on an as-needed basis, not preallocating a large chunk of resources for each user. For example, Apache might assign 8MB to a user, while Node assigns 8KB.

What makes Node different?


The way that Node is more efficient on servers is by not allocating resources to things while it waits, says Hughes-Croucher. Say you have to talk to the database, and thats going to take 50ms to respond. Instead of assigning all of the processing resources for that 50ms wait, it just uses a placeholder. When the database responds, then it allocates the resources needed to process. That means its totally possible to do a lot more requests at once, because you only allocate the server resources when you need to use them, not while you are waiting on databases.

hands on code: hello world!


<?php //helloworld.php echo "hello"; sleep(2); echo "world!"; ?>

//helloworld.js setTimeout(function(){ console.log("world!"); }, 2000); console.log("hello");

There is no waisted time on the node program, the thread is idle not waiting

hands on code: http server


var http = require("http") ; var server = http.createServer(function(req, res){ res.writeHead(200, {"content-type":"text/plain"}); res.end("Hello World!\n"); }).listen(8000);

Headers of the request are:


HTTP/1.1 200 OK content-type: text/plain Connection: keep-alive Transfer-Encoding: chunked

hands on code: not only http


var net = require("net") ; net.createServer(function(socket){ socket.on("data", function(data){ socket.write(data); }); }).listen(8000);

hands on code: telnet chat


var net = require("net"); var clients = []; net.createServer(function(socket){ clients.push(socket); socket.on("data", function(data){ for(var i = 0; i < clients.length; i++){ if(clients[i] == socket) continue; clients[i].write(data); } }); socket.on("end", function(){ var index = clients.indexOf(socket); clients.splice(index, 1); }); }).listen(8000);

hands on code: Async I/O


var fs = require("fs") , sys = require("sys");; fs.readFile("/home/cherta/workspace/samples/foo.txt", function(err, data){ if(err) throw err; sys.puts(data) }); console.log("Antes de foo?");

What is node.js?
It's a set of tools and libraries living on top of the V8.

What is not node.js?


A super framework that would change your life. Assuming that your life will change for a crappy piece of software

Working on top of node


There are killer frameworks that will make your life easier using node. Express web framework Socket IO

Express
Web framework working on top of node.js High Performance Template engines support (jade, ejs) CSS engines support (sass, less, stylus) Partials support
var app = express.createServer(); app.get('/', function(req, res){ res.send('Hello World'); }); app.listen(3000);

Socket I/O

Socket.IO is a Node.JS project that makes WebSockets and realtime possible in all browsers. It also enhances WebSockets by providing built-in multiplexing, horizontal scalability, automatic JSON encoding/decoding, and more.

A Simple Static File Server


Any HTTP server must be able to send static files such as HTML files, images and other files. The following code does just that:

var sys = require("sys"), http = require("http"), url = require("url"), path = require("path"), fs = require("fs"); http.createServer(function(request, response) { var uri = url.parse(request.url).pathname; var filename = path.join(process.cwd(), uri); path.exists(filename, function(exists) { if(!exists) { response.sendHeader(404, {"Content-Type": "text/plain"}); response.write("404 Not Found\n"); response.close(); return; }

A Simple Static File Server


Any HTTP server must be able to send static files such as HTML files, images and other files. The following code does just that:

fs.readFile(filename, "binary", function(err, file) { if(err) { response.sendHeader(500, {"Content-Type": "text/plain"}); response.write(err + "\n"); response.close(); return; }
response.sendHeader(200); response.write(file, "binary"); response.close(); }); }); }).listen(8080); sys.puts("Server running at http://localhost:8080/");

A Simple Static File Server


We start by requiring all of the modules that we will need in our code. This includes the sys, http, url, path, and fs or filesystem modules. Next we create an HTTP server like we did before. This time, we will use the url module to parse the incoming URL of the request and find the pathname of the file being accessed. We find the actual filename on the servers hard drive by using path.join, which joins process.cwd(), or the current working directory, with the path to the file being requested. Next, we check if the file exists, which is an asynchronous operation and thus requires a callback. If the file does not exist, a 404 Not Found message is sent to the user and the function returns. Otherwise, we read the file using the fs module using the binary encoding, and send the file to the user. If there is an error reading the file, we present the error message to the user, and close the connection. Because all of this is asynchronous, the server is able to serve other requests while reading the file from the disk no matter how large it is. If you run this example, and navigate to http://localhost:8080/path/to/file, that file will be shown in your browser.

A Simple Static File Server

You might also like