Using the Raspberry Pi as a server, the script
It must be able to provide data on request to another device, or execute programs on command.
Installing a service and data server with Node.js
You should preferably have a recent version of Node, not the version 0.10 provided in Raspbian! To install it automatically, here is a little script:
#!/bin/sh
curl -sL https://deb.nodesource.com/setup_6.x | sudo -E bash -
sudo apt-get install -y nodejs
The script must be done on the Raspberry of Linux and not on Windows, because the shell is sensitive to end-of-line codes. To do this, type:
leafpad instnode
Then copy the code above (this assumes that this page is loaded on the Pi browser). You can also download the script in a zip archive to decompress on the Pi.
No sudo here because it is as a user and not as administrator that one uses the script. You must then change the permissions to make it executable. Right-click on the file name from the file manager, on access rights, and change "make executable" to "for everyone".
You can then run the script by:
./instnode
Optionally, you can create a folder for your server, on a user account, by default in /home/pi.
mkdir www
The server root will be:
/home/pi/www
The server is a simple JavaScript program that is launched to put the Pi online. To put Pi and other computers into a network, sending HTML pages is not the goal, it is mainly to send commands and receive data. Here is an example of a server that executes commands and in return sends information. Asynchronously.
1) The Node.js server
This service server does not send files to a browser, a script that does this is provided in another article, Making a Page Server with Node.js. It receives the name of a script and data to pass to that script and executes the corresponding command.
var runner = require("child_process"),
http = require("http"),
path = require("path"),
url = require("url"),
fs = require("fs");
function sendError(errCode, errString, response)
{
response.writeHeader(errCode, {"Content-Type": "text/plain"});
response.write(errString + "\n");
response.end();
return;
}
function sendData(err, content, response)
{
if(err) return sendError(500, err, response);
response.writeHeader(200, {"Content-Type": "text/plain"});
response.write(content + "\n");
response.end();
}
/*
Run a script
This script will send data to the user when it wants.
*/
function runScript(params, response)
{
var command = "";
if(params.script == undefined) return;
if(params.data == undefined) return;
var child = runner.execFile("node",
[params.script, params.data],
function(error, stdout, stderr) {
console.log(error + " " + stdout);
sendData(error, stdout, response);
});
child.on('close', function(code) {
process.exit(1);
});
}
function getCommand(request, response)
{
if(request.method != "POST") {
console.log("POST only supported.");
return;
}
var data = "";
request.on("data", function(chunk) {
data += chunk;
});
request.on("end", function() {
var urlpath = url.parse(request.url).pathname;
if(urlpath == "favicon.ico") return;
var localpath = path.join(process.cwd(), urlpath);
console.log("Requested script: " + localpath);
fs.exists(localpath, function(result) {
var params = {
"script": localpath,
"data" : "\"" + data + "\""
};
runScript(params, response);
});
});
}
var server = http.createServer(getCommand);
server.listen(3000);
console.log("Server available...");
The code has the necessary functions to create a server, run a script, and pass data to this script. It returns to the origin ot the request the result displayed by the script.
2) An example of a very basic service
This demonstration script receives and displays the data sent by the remote computer to the raspi. In response, it sends the message "Hello computer!".
function processCommand(data) {
console.log("Received from computer: " + data);
var answer = "Hello computer!";
console.log("Answer:");
console.log(answer);
}
console.log("\nRaspberry: Starting script.js...");
var data = process.argv[2];
processCommand(data);
3) Code for use of the service by another computer
This is again a JavaScript command-line script, but any other language or interface might be appropriate. It sends to the server the name of a script (script.js) and the data to be processed, in this case the message "Hello Raspi!".
It then displays the answer sent by the script from the raspi.
http = require("http");
var options = {
host: 'xxx.xxx.xxx.xxx', // the IP of your Raspberry Pi
path: '/script.js',
port: '3000',
method: 'POST'
};
function received(response) {
var message = ''
response.on('data', function (chunk) {
message += chunk;
});
response.on('end', function () {
console.log(message);
});
}
var req = http.request(options, received);
req.write("Hello Raspi!");
req.end();
To run the script, you must assign the IP address of your raspi to the optional host attribute. Then you can also choose from several scripts and send them data according to your needs...
This code is perfectly functional, but deliberately simplified. One can improve the server with a list of scripts to choose from and exchanging JSON objects instead of simple messages. The principle is the same with the use of stringify and parse methods. Another improvement would be to use Wifi rather than the Internet, which would be better for most projects under Raspberry. This will be the subject of the following articles.
Download the code:
Start.js and script.js are stored on the raspi in the user's directory. The server is started by the command "node start.js".
Computer.js is stored on the device which has to communicate with the raspi. The script is launched by "node computer.js".