Getting started with node

Unless you’ve been living in a cave for more than one year, you’ve probably heard about node.js. Node is a tool allowing you, in command line, to execute javascript applications. The applications will run with V8, the chrome engine.

So nod allows to build javascript applications. It’s not a revolution which will make us stop programming in Ruby, Python or any other. It’s only one technology more with it’s advantages and problems.

Install Node

Node is only a command line tool. However some libraries are available. Let’s start by downloading the project on github. Then open a command line and go to the node’s folder.

./configure && make && make install

You now have node installed on your machine. You can execute any script with the following command :

node <filename.js>
Node isn't available on windows. You'll have to install a virtual machine and execute it in it.

How does it works ?

Let’s write a simple application which will read and write a file.

var fs = require('fs');
var sys = require('sys');

fs.readFile('todolist.txt', function(list) {
    sys.puts("What I have to do today: " + list);
});

fs.writeFile('todolist.txt', "Write the introduction to ndoe.js");

Our script does two things. First it reads the file “todolist.txt” and displays it’s content. Then it updates the file, giving it a task as content.

And on the web ?

If you’ve already heard about node until now, it’s probably because of what it offers to program asynchronus applications, notably with WebSockets.

Let’s take right now a very basic application :

var sys = require('sys');
var net = require('net');

Array.prototype.remove = function(e) {
    for (var i = 0; i < this.length; i++) {
        if (e == this[i]) { return this.splice(i, 1); }
    }
};

var clients = [];

function Client(socket) {
    this.socket = socket;
}


var server = net.createServer(function (socket) {
    var client = new Client(socket);
    clients.push(client);

    socket.addListener("connect", function () {
        clients.forEach(function(c) {
            c.socket.write("One people more ! We are now " + clients.length + " connected.\r\n");
        });
    });

    socket.addListener("data", function(data) {
       socket.write(data);
    });


    socket.addListener("end", function () {
        clients.remove(client);
        clients.forEach(function(c) {
            c.socket.write("We now are one less\n");
        });
        socket.end();
    });
});
server.listen(7000, "localhost");

What this application does is very simple. For every client which connects himself, it transmits a message to all the ones who already are and tells them there’s a newcomer. It also tells how many persons there’s now. And every time someone disconnects himself, it removes himself from the list.

You can try it yourself locally by opening the page in chrome and in firefox. Let’s analyze this code in detail.

var sys = require('sys');
var net = require('net');

Here, we include the two libraries we’ll use in our application. The sys library is the node core. You’ll probably need it in all of your applications.

The net library allows us to start a server.

You can see the list of all the native libraries in the node’s lib folder.

Array.prototype.remove = function(e) {
    for (var i = 0; i < this.length; i++) {
        if (e == this[i]) { return this.splice(i, 1); }
    }
};

Natively, javascript doesn’t have any method to delete an element from an array unless we know it’s position. So we add a javascript method to do that. We’ll use it later.

var clients = [];

This is the node magic. It’s single thread and it’s not a bug ! So the clients array which we declare here will be available for all the persons using our application at the same time. Consequently, when we add an element in this array, this element is available for everybody.

This will allow to know, permanently, how many persons are connected to your application and to communicate with them.

function Client(socket) {
    this.socket = socket;
}

Every element in your array will be an instance of this Client object. The socket var is a pointer to the user’s socket. So we will be able to transmit a new message to the user at any moment.

var server = net.createServer(function (socket) {
    ...
}
server.listen(7000, "localhost");

We are now at the server part by itself. We create here a server object which we will execute to listen on the port 7000 on localhost.

When a client connects himself, the anonymus function we create here will be called and the socket parameter will correspond to the pointer to the client’s socket. Like that we can really interact with the users by detecting when he connects, disconnects and even when he transmits a message.

Here, we voluntarily use the "net" library because we don't specifically build an HTTP service. However there's an [http](http://nodejs.org/api/http.html) library which would be better for a website.
var client = new Client(socket);
clients.push(client);

The list of all the connected clients won’t update itself automatically. Consequently we must update it when the user loads the application.

socket.addListener("connect", function () {
    clients.forEach(function(c) {
        c.socket.write("One people more ! We are now " + clients.length + " connected.\r\n");
    });
});

A client’s socket can receive several listeners. It’s a method which will be executed when a precise event happend. Here, it’s the “connect” event.

In this event, we will loop through the clients array. And to every one of them we will send the message saying a new user just connected himself and how many we are now.

socket.addListener("data", function(data) {
   socket.write(data);
});

The user can transmis messages to the server. Here, we just display to that same client the messages he sends to us. So when you load the application, you’ll be able to see on the page all the headers transmitted to the server.

socket.addListener("end", function () {
    clients.remove(client);
    clients.forEach(function(c) {
        c.socket.write("We now are one less\n");
    });
    socket.end();
});

Finally we add one last event : when the user closes his connection with the server (or because he times out), we delete that client from the array (we’re using the “remove” method defined in javascript arrays previously).

Finally we inform all the remaining users that we are now one person less. And we close the socket in order to avoid any memory leak.

Conclusion

We’ve seen in that article a quick introduction to node.js. Many other features are however available. I highly invite you to take a look to the project’s documentation for more informations.