Raspberry Pi likes Node.js

Index To the Series
1. Raspberery Pi likes Open Source
2. Cross-Compiling for Raspberry Pi
3. Cross-Compiling ITK for Raspberry Pi
4. Raspberry Pi likes VTK
5. Raspberry Pi likes Node.js

 


Following on our series exploring the use of the Raspberry Pi,
Here we describe how to use Node.js natively in the board.

 

From the O’Reilly Book:   “Learning Node” by Sheelly Powers

 

Node.js is a server-side technology that’s based on Google’s V8 JavaScript engine.
It’s a highly scalable system that uses asynchronous,
event-driven I/O (input/output), rather than threads or separate process.
It’s ideal for web applications that are frequently accessed but computationally simple.

 

Hopefully this illustrates why the Raspberry Pi is hungry for running node.js.

This opens the possibilities for using the board to control “stuff”, and to drive such
controls from remote clients that are connecting to the board using a node.js
server running in the board itself.

Let’s say that you have a nuclear reactor in your basement, and while you
are away in vacations you are curious to monitor the temperature of the core
(you know… just in case…). Here you go, connect the measurements of the
core thermometer to the GPIO pins of the Pi, and feed the data through your
node.js server to a client that you are running in the Linux laptop that you
(as any self-respected Geek) brought to the beach. A cell phone with web
access will do the trick as well, if you are trying to keep appearances…

 


 

Note: as with the previous posts, many of the screenshot images below
may appear blurred due to subsampling. Please simply click on them,
to see them in full resolution, where the text will be clearly readable.

 

Step 1. Installing Node.js

This step is just too easy:

The node.js package has already been ported to ARM and it is included in
the Linux Raspbian distribution.

We just log in our Raspberry Pi and do:

sudo apt-get install nodejs

then happily answer “Y”, and we are on our way…

 

Step 2. Simple Ping-like HTTP Server

Let’s start with a simple server.

The minimal question that you have when you are at the beach is:

Has the house blown up yet ?

The following node.js code will answer the questions on a continuous basis

var http = require(‘http’);

http.createServer( function(req,res) {

   var currentTime = new Date();
   console.log(‘Client called at ‘+currentTime);

   res.writeHead(200, {‘Content-Type’:’text/plain’});
   res.write(‘The House is still here…\n’);
   res.write(‘Enjoy the Beach !\n’);
   res.end();

}).listen(‘8124’);

We write this code in a file named “http_server.js”
and run it in the Pi with the command:

nodejs  ./http_server.js

This short program creates an HTTP server listening at port 8124.

Then, from our computer at the beach, we open a web browser
and put the IP address of the Pi and the port 8124 as for example:

http://192.168.1.169:8124

and we see in the Pi server:

and in the client browser:

 
NOTE 1: We are assuming here that you already did all the magic required for
exposing your Pi as a public IP address from your home network, so that you,
and anyone else can check that your house is still there. That’s something
that you will do in your home router.

NOTE 2: If the server fails to respond to your query, Don’t Panic just yet.
Your reactor core may have melted, that’s one possibility, but it may also
be that you lost power in your house, or that your ISP disconnected your
service from some unfounded Copyright violation claim.

 

Step 3. Querying the HTTP Server

Since our previous server is just sending one bit of information back,
we can improve it to query for more detailed data.  To do this, we take
advantage of the mechanism of adding query strings to the URL that
we use to communicate with the server.

Let’s start by modifying the server’s code to be:

var http = require(‘http’);

http.createServer( function(req,res) {

   var query = require(‘url’).parse(req.url).query;
   requested_measurement = require(‘querystring’).parse(query).measurement;

   var currentTime = new Date();
   console.log(‘Client called at ‘+currentTime);

   // values to get from GPIO
   var temperature = 2000;
   var pressure = 5000;

   res.writeHead(200, {‘Content-Type’:’text/plain’});

   switch( requested_measurement ) {
     case ‘temperature’:
       res.write(‘Core Temperature = ‘ + temperature + ‘ K\n’);
       break;
     case ‘pressure’:
       res.write(‘Core Pressure = ‘ + pressure + ‘ PSI\n’);
       break
     }

   res.write(‘Enjoy the Beach !\n’);
   res.end();

}).listen(‘8124’);

We write this code in a file named “http_server_measures.js”
and run it in the Pi with the command:

nodejs  ./http_server_measures.js

This short program creates an HTTP server listening in port 8124.

Then, from our computer at the beach, we open a web browser
and put the IP address of the Pi and the port 8124 as we did before,
but this time we add a query string indicating what measurement we
want to get from our nuclear reactor. For example:

http://192.168.1.169:8124?measurement=temperature

or:

http://192.168.1.169:8124?measurement=pressure

and we see in the Pi server:

and in the Client browser:

 

 

 

Step 4. Streaming data with UDP

As you are there, sitting at the beach, you may get tired of refreshing
you browser page to get new data.

Let’s do now a more interesting connection, by using UDP instead of HTTP.

In this case, we are going to set up in the Raspberry Pi, a UDP server, that
when connected to a client, will start sending temperature data at regular
intervals.  To do this, we are going to use node.js also on the client side,
so, now you really need to bring that Linux laptop to the beach…

First we write the Server side code:

var dgram = require(‘dgram’);
var server = dgram.createSocket(“udp4”);

var client;   // global to store the client information
var interval; // global to store the interval timeout


function reportValue(remote) {
  var temperature = 5000; // get this from GPIO
  var currentTime = new Date();

  var message = new Buffer(‘Temperature= ‘+temperature+’ K at ‘+currentTime+’\n’);

  server.send(message, 0, message.length, remote.port, remote.address, function(err, bytes) {
    console.log(err);
});

  console.log(‘Sent ‘+message);
}


server.on(‘listening’, function () {
    var address = server.address();
    console.log(‘UDP Server listening on ‘ + address.address + “:” + address.port);
});

server.on(‘close’, function () {
    console.log(‘Client closed connection’);
    clearInterval(interval); // do not send more messages to client
});

server.on(‘message’, function(message,remote) {
  console.log(‘We got a client from ‘+remote.address+’:’+remote.port);
  client = remote;

  var timeInterval = 1500; // milliseconds
  interval = setInterval(reportValue, timeInterval, client);
});

var localport=41234;
server.bind(localport);

Now we write the client side:

var dgram = require(‘dgram’);
var client = dgram.createSocket(“udp4”);

var counter = 0;

client.on(‘message’, function (message, remote) {
    console.log(remote.address + ‘:’ + remote.port +’ – ‘ + message);
    counter++;

    if( counter > 5) {  // stop after receiving 5 measurements
      client.close();
      }
});


var address = ‘raspberrypi’;
var port = 41234;

var message = new Buffer(‘Please send me temperatures’);

client.send(message, 0, message.length, port, address, function(err, bytes) {
    if (err) throw err;
    console.log(‘UDP message sent to ‘ + address +’:’+ port);
});

We then run the server in the Pi, and the client in a remote laptop,
and we get on the Pi server:

and we get the following on the Laptop remote client:

 More details at:

 


 

And this concludes our tour of Node.js in Raspberry Pi.

Enjoy the Beach !

4 Responses to Raspberry Pi likes Node.js

  1. Trevor Joseph says:

    Where do you save the http_server.js file

  2. Trevor Joseph says:

    Ignore that last post. got it working

  3. Spike McLarty says:

    and if like me you want your mom to be able to check on your reactor while you are snorkeling, don’t forget that ports < 1024 are privileged, so if you edit the port to be 80 you need sudo: sudo nodejs http_server.js

  4. and vice versa? I want to send a whole mess of data (from the same pi) to the gpio pins. (Exactly: A bytestream of the screen on the browser, which is rendered with pixi.js -> to light up a selfmade LED screen.)

Questions or comments are always welcome!