Node by example

Node by example: 4. Basics

4. Basics

The complete source code can be downloaded here: http://github.com/Hendrik/node-by-example

Encodings:
Node.JS supports UTF-8 ("utf8"), ASCII ("ascii") and Binary ("binary").
ASCII and Binary are relatively fast, UTF-8 is slower and should be avoided when possible.

Globals: [1]
i) Arguments:
See 04_Basics/global.js:

var sys = require("sys"),
    some_argument = process.argv[2];

// argument example
if (!some_argument) {
  return sys.puts("Usage: node " + __filename.replace(__dirname + "/", "") + " some_argument");
}

// require example
sys.puts("Default require.paths: " + require.paths);
sys.puts("Adding current directory to require.paths");
require.paths.unshift(__dirname);
sys.puts("Modified require.paths: " + require.paths);


run it via

node global.js test_arg

The output will be something like:

Default require.paths: /root/.node_libraries
Adding current directory to require.paths
Modified require.paths: /usr/src/node-by-example/04_Basics,/root/.node_libraries

process.argv is an array containing the command line arguments.

some_argument = process.argv[2];

In this case "node" would be argv[0], "global.js" argv[1] and "test_arg" argv[2].

if (!some_argument) {
  return sys.puts("Usage: node " + __filename.replace(__dirname + "/", "") + " some_argument");
}

If a command line argument is not provided, the script will output the correct usage, where __filename is the global object for the name of the currently executed file and __dirname is the name of the directory of the currently executed code.

 

ii) require

require.paths

provides the search path for absolute path arguments to require()
You can add a directory to the search path by unshifting the new directory to require.paths:

require.paths.unshift(__dirname); // adds the current directory to the search directory

 

Process: [2]

The process Object provides information about the currently running process, such as its process ID, the platform it is running on, memory usage, ...

You can exit a script by providing an exit code, e.g.:

process.exit(0);

By default it exits using success code 0. See 04_Basics/process.js:

var sys = require("sys");

// display all command line arguments
sys.puts("Provided arguments:");
for (var key in process.argv) {
  sys.puts(key + ": " + process.argv[key]);
}

// process details (PID, platform, memory usage)
sys.puts("\nPID: " + process.pid);
sys.puts("Platform: " + process.platform);
sys.puts("Memory usage: " + process.memoryUsage().rss);

// display user environment
sys.puts("\nUser Environment:");
for (var key in process.env) {
  sys.puts(key + ": " + process.env[key]);
}

// process exit code - default: success code 0
process.exit(0);

 

System module: [3]

The system module provides various ways to send output to the console.

sys.puts()

outputs the string with a trailing newline.

 

sys.print()

outputs the string without any newline.

 

sys.debug("Some debug output")

outputs the string preceeded by "DEBUG: ", e.g.:

DEBUG: Some debug output

 

sys.log("Some log output")

outputs the string preceeded by the current date & time, e.g.:

20 Mar 23:17:15 - Some log output

 

sys.inspect(process.memoryUsage())

outputs a string representation of the provided object, e.g.:

{ rss: 5263360
, vsize: 41353216
, heapTotal: 2176512
, heapUsed: 963872
}

See 04_Basics/sys.js:

var sys = require("sys");

// sys output examples
sys.puts("Output with trailing newline");
sys.print("Output without ");
sys.print("new line");
sys.puts("\nAdd newline to begining and extra one at the end.\n");
sys.debug("Some debug output");
sys.log("Some log output");

// simple sys.inspect example
var process_memory = process.memoryUsage();
sys.puts("\nprocess.memoryUsage():");
sys.puts(sys.inspect(process_memory));

 

Timers: [4]

You can use the JavaScript timers, such as setTimeout(), clearTimeout(), setInterval(), clearInterval() in your node apps.

See 04_Basics/timers.js:

var sys = require("sys");

// simple timout example - waits for 2sec before continuing with the next step
var start_time = new Date();
sys.puts("Starting 2 second timer");
setTimeout(function() {
  var end_time = new Date();
  var difference = end_time.getTime() - start_time.getTime();
  sys.puts("Stopped timer after " + Math.round(difference/1000) + " seconds");
  cleartimeout_example();
}, 2000);

// clearTimeout example - timout set for 30secs, gets cancelled via clearTimeout right away, no output
function cleartimeout_example() {
  var start_time = new Date();
  sys.puts("\nStarting 30 second timer and stopping it immediately without triggering callback");
  var timeout = setTimeout(function() {
    var end_time = new Date();
    var difference = end_time.getTime() - start_time.getTime();
    sys.puts("Stopped timer after " + Math.round(difference/1000) + " seconds");
  }, 30000);
  clearTimeout(timeout);
  interval_example();
}

// interval example - 5x output every 2secs using setInterval
function interval_example() {
  var start_time = new Date();
  sys.puts("\nStarting 2 second interval, stopped after 5th tick");
  var count = 1;
  var interval = setInterval(function() {
    if (count == 5) clearInterval(this);
    var end_time = new Date();
    var difference = end_time.getTime() - start_time.getTime();
    sys.puts("Tick no. " + count + " after " + Math.round(difference/1000) + " seconds");
    count++;
  }, 2000);
}

 

[1] http://nodejs.org/api.html#global-objects-38
[2] http://nodejs.org/api.html#process-46
[3] http://nodejs.org/api.html#sys-68
[4] http://nodejs.org/api.html#timers-74

Node by example

Node by example: 3. Modules

3. Modules

The complete source code can be downloaded here: http://github.com/Hendrik/node-by-example

As mentioned in the previous chapter, you use

var some_var = require("built-in_module_name");

to include one of Node.JS's built-in modules.

What if you want to include your own module?
Node.JS uses the CommonJS module system [1], so that it is easy to add your own modules to your script.

Lets start with the script that is going to include our module, modules.js:

var foobar = require("./foobar"),
      sys = require("sys");

sys.puts("Foobar: " + foobar.bar("bar"));

If you include a built-in module, then you use

require("module_name");

but if you wish to use a custom module named "module_name.js", then you use

require("./module_name");

Please note: the ".js" is omitted.
./ indicates the directory relative to the file calling require().
This would change to the following, if your module was located in the "libs" subdirectory relative to the file calling require():

require("./libs/module_name");

Alternatively you can also provide the full path to the module:

require("/path/to/module_name");

The next line outputs "Foobar: " plus some output taken from the foobar.js module:

sys.puts("Foobar: " + foobar.bar("bar"));

Lets take a look at the foobar.js module:

var foo = 'Foo';

exports.foo = function() {
  return foo;
};

exports.bar = function(bar) {
  return foo + bar;
};

Any variable defined in a module is private, so its scope is limited to the module.
In this case the local variable "foo" is private to foobar.js

var foo = 'Foo';

foobar.js has exported 2 functions foo() and bar(), which you can then use in the file calling require() for the module.

modules.js used:

sys.puts("Foobar: " + foobar.bar("bar"));

so it calls the bar() function of the foobar.js module passing "bar" as a string to it.
The result is the "Foobar" output.

More information on the Node.JS module system: http://nodejs.org/api.html#_modules


[1] CommonJS Modules Spec: http://commonjs.org/specs/modules/1.0/

 

Node by example

Node by example: 2. Hello World

2. Hello World

The complete source code can be downloaded here: http://github.com/Hendrik/node-by-example

It's the same old same old, but here goes:
The Node.JS "Hello World" example is a http server that serves a "Hello World" output 2 seconds after a client connects to the server.

var sys = require('sys'),
http = require('http');

http.createServer(function(req, res) {
  setTimeout(function() {
    res.writeHead(200, {'Content-Type': 'text/plain'});
    res.write('Hello World');
    res.close();
  }, 2000);
}).listen(8000);
sys.puts('Server running at http://127.0.0.1:8000');

Run the code via:

node hello_world.js

Now open your browser and access http://127.0.0.1:8000 or the IP/URL of the remote server, in case you are running the code not on your local machine.

The code in detail:
At first we include 2 of Node.JS built-in modules, "sys" and "http", by using the

var some_var = require("built-in_module_name");

command:

var sys = require('sys'),
  http = require('http');

The "sys" module provides features to output data to the command line, for example.
The "http" module provides the needed HTTP server feature for this code sample.
You can include your own modules, more on that in the next part.

Next we create the HTTP server and make it listen to port 8000:

http.createServer(function(request, response) {
...
}).listen(8000);

The request object contains details about the request, such as the request method (GET, POST, DELETE, ...), the request URL, headers, ...
and the response object is used to send a response to the request, such as the "Hello World" output.

As mentioned before, the server waits 2 seconds before sending any output, which is what the setTimeout() function is used for.setTimeout(function() { ... }, 2000);After the 2 seconds are over the code in the provided callback is executed:

response.writeHead(200, {'Content-Type': 'text/plain'});
response.write('Hello World');
response.close();
First we send a header to the client with the status code 200 (OK) and the content-type specified as text/plain.
After sending the header you can send data to the client using the response.write() function.
Only thing left is to close the response, which signals to the server that all of the response headers and body have been sent. This method *must* be called on each response!

The last line outputs "Server running at http://127.0.0.1:8000" to the command line, once you start the script:
sys.puts('Server running at http://127.0.0.1:8000');
That's it. With just a few lines of code you have a simple HTTP server up & running that serves "Hello World" to any client requests.

Node by example

Node by example: 1. Introduction & Installation

i. Introduction

node-by-example is a collection of short code samples, that showcase some of the available features using Node.JS
The code samples are based on the Node.JS documentation, its unit test code, code posted online and made up by myself.

You can download the code here: http://github.com/Hendrik/node-by-example

I assume you are familiar with JavaScript and already know what Node.JS is, so that I will skip the introduction of Node.JS itself and jump right into the first code sample.

For more details about Node.JS itself please see the official website ( http://nodejs.org/ ) and Ryan Dahl's JSConf 2009 presentation about Node.JS ( http://blip.tv/file/2899135 )



1. Installation

The following is a list of the required apps & modules needed to run all of the provided code samples.
You only need node.js to get started, the rest is required for the later parts.

Apps:

 

node.js Modules:

 

Other:


Node.JS installation:
You can download the latest release here: http://nodejs.org/#download

Node eventually wants to support all POSIX operating systems (including Windows with MinGW) but at the moment it is only being tested on Linux, Macintosh, and FreeBSD. The build system requires Python 2.4 or better. V8, on which Node is built, supports only IA-32 and ARM processors. V8 is included in the Node distribution. To use TLS, GnuTLS and libgpg-error are required. There are no other dependencies. [1]

After you have downloaded the source run:

./configure
make
make install

to install Node.JS, then run

make test

to run the tests.





[1] Official Node.JS build instructions: http://nodejs.org/#build

My 2c

Welcome to the new blog

Welcome to the new OSButler blog, django powered!

Due to the changes in the URL - the OSButler blog is now hosted at blog.osbutler.com - I had to import some of the older posts, which are still receiving page views, but others got the boot as they are now outdated, e.g.: the OpenSuse 11 experience, outdated Linux distros comparisons, ...

However, those will be revived in the near future with up2date data, so stay tuned for further posts later on.

The blog now also features an open comment system, so feel free to share your thoughts as well.

A new category is "Reviews", where I will post my praises & complaints about specific books and apps.

Previous Posts Next Posts