NodeJS

So, tonight I ventured into the realm of NodeJS, and I wanted to share what I have learned. I went into this process knowing virtually nothing about what I was getting myself into; so under the assumption that there are other beginners out there, I hope that I can make this overview very simple.

Before I even got into the installation portion of NodeJS, I stood up a VirtualBox to play around in. I’ve learned (many times the hard way) that it’s always good to set up a sandbox to try out new tech. Therefore, if you screw something up, you can just trash the install and start over. Installing a VM of Ubuntu took about a half hour. Sharing a folder from the host to a mount on the guest took about 15 minutes longer to figure out. I’ve found that it’s easier/safer to develop and save files outside of the virtual machine, just in case I irreparably damage it.

Once that was done, I downloaded NodeJS from http://nodejs.org/#download and saved it to my Home folder. I extracted the files, and navigated to that directory via the command line. Three simple commands later, and it was installed:

./configure
make
sudo make install

It does require that you have a C++ compiler installed (which was not available in my base Ubuntu installation), but installing that was simple enough:

sudo apt-get install g++

After “make install”, you can test your installation by running:

make test

This will run through a battery of tests, and show you where your installation is lacking. I had two errors thrown back at me: “Error: node.js not compiled with openssl crypto support.” and “Error: Command failed: /bin/sh: curl: not found”. Each are simple to resolve:

sudo apt-get install curl
sudo apt-get install libssl-dev

And that did it. “Hello World” was incredibly easy to set up:

var http = require("http");
http.createServer(function(req, res) {
    res.writeHead(200, {"Content-Type" : "text/plain"});
    res.end("Hello World\n");
}).listen(8124, "127.0.0.1");

I saved that file as hello.js and executed:

node hello.js

Then, I went to a web browser, typed in the url http://localhost:8124 and saw “Hello World” appear as the webpage. Success!

So, I proceeded to create a more “real world” example, just to explore the framework a bit more. So, I set out to create a chat server and client. I’ve always been a fan of Javascript, due to its relative simplicity and flexibility, but I truly believe that NodeJS is where it shines. For the past several years, I have done much more work on the web than I have on desktop applications, so being able to apply the same event-driven coding paradigms is a very welcome sight. And thinking more about it, so much of what we build in interactive applications actually IS based on events, even if we refer to it as polling. So, here’s what I came up with:

server.js:

var net = require("net");

var streams = [];
var server = net.createServer(function(stream) {

    stream.setEncoding("utf8");
    stream.on("connect", function() {
        streams.push(stream);
        stream.write("[System] Connection Established");
    });

    stream.on("end", function() {});

    stream.on("data", function(data) {
        data = data ? String(data) : "";
        for(var i=0; i<streams.length; i++) {
            if(stream != streams[i]) {
                streams[i].write(data.replace(/\s+$/,""));
            }
        }
    });

});

server.listen(8124, 'localhost', function() { console.log("server has been bound."); });

var commands = {
    "exit" : function() { process.exit(); }
};

var stdin = process.openStdin();
stdin.on('data', function(chunk) {
    var command = chunk ? String(chunk) : "";
    command = command.replace(/^\s+|\s+$/,"");
    if(command.indexOf(".") == 0 && (command.substr(1) in commands)) {
        commands[command.substr(1)]();
    }
});

client.js:

var net = require("net");

var username = process.argv[2] || null;
if(!username) {
    console.log("No username supplied.");
    process.exit();
}

var commands = {
    "exit" : function() { process.exit(); }
};

var connection = net.createConnection(8124, "localhost");

connection.setEncoding("utf8");
connection.on("connect", function() {

    var stdin = process.openStdin();
    stdin.on('data', function(chunk) {

        var command = chunk ? String(chunk) : "";
        command = command.replace(/^\s+|\s+$/,"");
        if(command.indexOf(".") == 0 && (command.substr(1) in commands)) {
            commands[command.substr(1)]();
            return;
        }

        connection.write("["+username+"] " + chunk);
    });

    stdin.on("end", function(){});
});

connection.on("data", function(data) { console.log(data); });
connection.on("error", function(exception) { console.log("[Exception] " + exception); });
connection.on("timeout", function() { console.log("[Connection Timed Out]"); });
connection.on("close", function() { console.log("[Connection Closed]"); });

So, to execute (each in their own terminal window):

node server.js
node client.js username1
node client.js username2

And that’s it. Obviously it’s not a terribly robust application, but it’s amazing what can be done in so few lines of code.

Next I am going to attempt to install the CouchDB modules and build on top of this. Until next time…

Leave a comment

2 Comments.

  1. Absolutely agree. Didn’t exactly understand “timeout”, function() until now. Thanks. Hope all is well.

  2. For get couch. Go with MongoDB!

Leave a Reply


[ Ctrl + Enter ]