NodeJS
Node.js is a platform built on Chrome's Javascript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.
http://blog.4psa.com/the-callback-syndrome-in-node-js/
SlackBuild Slackware64 14.0
Package 64 bit: node-0.10.12-x86_64-1_SBo.tgz
Sample app
main.js
1 var assert = require('assert'); // TDD
2 var fs = require('fs'); // file system
3 var util = require('util');
4 //--------------------
5 var Dummy = require('./dummy.js');
6 var Local = require('./local.js');
7 var conf=require('./config.js') // Configuration
8
9 console.log( conf.configX['foo'] );
10 console.log( conf.configX['bar'] );
11
12 var d1 = new Dummy(12345);
13 var d2 = new Dummy(67890);
14 var d3 = new Dummy(112233);
15
16 assert.equal(d1.methodA.call(d2),67890,'');
17 assert.equal(d1.methodA.call(d3),112233,'');
18 assert.equal(d3.methodA.call(d1),12345,'');
19
20 var l1 = new Local('local1',10,11);
21 var l2 = new Local('local2',20,21);
22 var l3 = new Local('local3',30,31);
23
24 assert.equal(l1.getPoint().getX(),10,'');
25 assert.equal(l2.getPoint().getX(),20,'');
26 assert.equal(l3.getPoint().getX(),30,'');
27
28 // async readdir
29 fs.readdir('/tmp', cbReaddir);
30
31 function cbReaddir(err,files){
32 for(var i=0; i< files.length;i++){
33 console.log(files[i]);
34 }
35 }
36
37 //async append file
38 fs.appendFile('/tmp/test.txt', 'data to append\r\n', cbAppendFile);
39
40 function cbAppendFile(err) {
41 if (!err) {
42 console.log('The "data to append" was appended to file!');
43 }
44 }
45
46 function hexcounter(value,callback){
47 console.log('HC:',value);
48 if(value<15){
49 setImmediate(function(){callback(value+1,callback);});
50 }
51 else{
52 setImmediate(function(){callback(0,callback);});
53 }
54 }
55
56 function octalcounter(){
57 var timeout=500;
58 if(arguments.length===1){
59 console.log('OC:',arguments[0]);
60 setTimeout(octalcounter,timeout,1,2)
61 }
62
63 if(arguments.length===2){
64 var a0=Number(arguments[0]);
65 var a1=Number(arguments[1]);
66 console.log(util.format('%s %d %d','OC:',a0,a1));
67 setTimeout(octalcounter,timeout,a0+1,a1+1);
68 }
69 }
70
71 hexcounter(2,hexcounter);
72 octalcounter(12300);
73
74 process.on('SIGHUP', onSIGHUP);
75 function onSIGHUP() {
76 console.log('SIGHUP received',arguments.length);
77 }
78
79 process.on('SIGTERM', onSIGTERM);
80 function onSIGTERM() {
81 console.log('SIGTERM received',arguments.length);
82 }
config.js
dummy.js
point.js
local.js
node-gyp
node-gyp is a cross-platform command-line tool written in Node.js for compiling native addon modules for Node.js.
https://github.com/TooTallNate/node-gyp
Install with npm
Hello world gyp
Based on https://github.com/joyent/node/tree/master/test/addons/hello-world
Based on https://github.com/rvagg/node-addon-examples
binding.gyp
{ "targets": [ { "target_name": "hello", "sources": [ "hello.cc" ] } ] }
hello.cc
1 #include <node.h>
2 #include <v8.h>
3
4 using namespace v8;
5
6 Handle<Value> Method(const Arguments& args) {
7 HandleScope scope;
8 return scope.Close(String::New("world"));
9 }
10
11 void init(Handle<Object> exports) {
12 exports->Set(String::NewSymbol("hello"),
13 FunctionTemplate::New(Method)->GetFunction());
14 }
15
16 NODE_MODULE(hello, init)
- nano hello.js
1 node hello.js
build.sh
Read text file example
1 var fs = require('fs'); // file system
2
3 function cbReadFile(err, data) {
4 if (err) {
5 throw err;
6 }
7 var ds = data.toString(); // data is of type Buffer
8 var buffer = '';
9 for ( var idx = 0; idx < ds.length; idx++) {
10 if (ds[idx] != '\n') {
11 buffer = buffer + ds[idx];
12 } else {
13 console.log(buffer);
14 buffer = '';
15 }
16 }
17
18 }
19
20 fs.readFile('/etc/passwd', cbReadFile);
Context with this and bind
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.
1 /*Constructor function*/
2 function Counter(){
3 this.counter=0;
4 }
5
6 Counter.prototype.run=function(){
7 console.log('counter:',this.counter);
8 this.counter++;
9 //recall run
10 setTimeout(this.run.bind(this),1000);
11 };
12
13 var c = new Counter();
14 setTimeout( c.run.bind(c) ,1000); // apply context of c to this
15
Install from source Node 4.6.0
Install node 6.9.1 on Slackware64 14.2
testApp with mongoose for AWS ElasticBeanstalk
Install Node 6.x in Ubuntu (vagrant on Windows)
Structure
. ├── app.js ├── config.js ├── index.html ├── package.json └── utils.js
app.js
1 /**
2 * npm install
3 * npm start
4 * MONGOURL=mongodb://127.0.0.1/testdb npm start
5 * mongo
6 * use testdb
7 * show collections
8 * dummies
9 * db.dummies.find()
10 *
11 * zip ../testAppNodeJS.zip app.js config.js index.html package.json utils.js
12 *
13 * Deploying an Artifact Instead of the Project Folder
14 * You can tell the EB CLI to deploy a ZIP or WAR file that you generate as part of a separate
15 * build process by adding the following lines to .elasticbeanstalk/config.yml in your project
16 * folder.
17 * deploy:
18 * artifact: path/to/buildartifact.zip
19 */
20 var mongoose = require('mongoose');
21 var http = require('http');
22 var ut = require('./utils')
23 var cfg = require('./config')
24
25 var dummyModel = mongoose.model('Dummy', mongoose.Schema( { foo: String }) );
26
27 mongoose.connect( cfg.getMongoURL() );
28
29 mongoose.connection.once('open', function(){
30 ut.log('Connected to ' + cfg.getMongoURL() );
31 var dummy = new dummyModel({ foo: 'Connected to MongoDB ' + new Date().toISOString() });
32 dummy.save();
33 });
34
35 function requestListener(req, res) {
36 if (req.method === ut.HTTP_METHOD_POST) {
37 var body = '';
38
39 req.on('data', function(chunk) {
40 body += chunk;
41 });
42
43 req.on('end', function() {
44 ut.log('Received URL ' + req.url );
45 if (req.url === '/') {
46 ut.log('Received message: ' + body);
47 } else if (req.url === '/scheduled') {
48 ut.log('Received task ' + req.headers['x-aws-sqsd-taskname'] + ' scheduled at ' + req.headers['x-aws-sqsd-scheduled-at']);
49 }
50 else if (req.url === '/addDummy') {
51 var dummy = req.headers['dummy'];
52 ut.log('Received dummy ' + dummy );
53 dummyModel.create({ foo: dummy });
54 }
55
56 res.writeHead(ut.HTTP_200_OK, 'OK', ut.getTextPlain() );
57 res.end();
58 });
59 }
60 else {
61 res.writeHead(ut.HTTP_200_OK);
62 res.write( ut.getIndex() );
63 res.end();
64 }
65 }
66
67 var server = http.createServer(requestListener);
68 // Listen on port 3000, IP defaults to 127.0.0.1
69 server.listen( cfg.getPort() );
70 // Put a friendly message on the terminal
71 ut.log('Server running at http://127.0.0.1:' + cfg.getPort() + '/');
72 ut.showEnvironmentVars();
config.js
1 // Constructor function
2 function Config(){
3 };
4
5 //Static
6 Config.getPort = function() {
7 return process.env.PORT || 8081;
8 };
9
10 Config.getTestVar = function() {
11 return process.env.TESTVAR || '????';
12 };
13
14 Config.getMongoURL = function() {
15 return process.env.MONGOURL || '????';
16 };
17
18 module.exports = Config
utils.js
1 var fs = require('fs');
2
3 // Constructor function
4 function Utils() {
5 };
6
7 // Constants
8 Utils.HTTP_METHOD_POST='POST';
9 Utils.HTTP_METHOD_GET='GET';
10 Utils.HTTP_200_OK=200;
11
12 // Static
13 Utils.showEnvironmentVars= function() {
14 Utils.log('## Environment variables ##');
15 for(var key in process.env){
16 Utils.log('Environment variable ' + key + '==' + process.env[key] );
17 }
18 };
19
20 Utils.log = function(entry) {
21 var msg = new Date().toISOString() + ' - ' + entry + '\n';
22 fs.appendFileSync('/tmp/sample-app.log', msg);
23 console.log(entry);
24 };
25
26 Utils.getIndex = function() {
27 return fs.readFileSync('index.html');
28 };
29
30 Utils.getTextPlain = function() {
31 return {'Content-Type': 'text/plain'};
32 };
33
34 module.exports = Utils
package.json
1 {
2 "name": "Elastic-Beanstalk-Sample-App",
3 "version": "0.0.1",
4 "private": true,
5 "dependencies": {
6 "mongoose":"latest"
7 },
8 "scripts": {
9 "start": "node app.js",
10 "package": "CURRDATE=$(date -u \"+%Y%m%dT%H%m%S%Z\"); rm testAppNodeJS*.zip; zip -r testAppNodeJS-$CURRDATE.zip app.js config.js index.html package.json utils.js node_modules"
11 }
12 }
index.html
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <title>Elastic Beanstalk VB test</title>
5 <style>
6 </style>
7 </head>
8 <body>
9 <div class="textColumn">
10 <h1>Congratulations</h1>
11 <p>Your first AWS Elastic Beanstalk Node.js application is now running on your own dedicated environment in the AWS Cloud</p>
12 </div>
13 <div class="linksColumn">
14 <h2>What's Next?</h2>
15 </div>
16 </body>
17 </html>
Install from source node 10.16.1
Usage of encodeURIComponent and decodeURIComponent