Skip to content

Commit

Permalink
build basic server structure, added a test Provider which connects to…
Browse files Browse the repository at this point in the history
… nmea gps, bumped version
  • Loading branch information
Fabian Tollenaar committed Apr 2, 2014
1 parent 4e924ac commit e338aab
Show file tree
Hide file tree
Showing 20 changed files with 964 additions and 0 deletions.
1 change: 1 addition & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('./lib');
24 changes: 24 additions & 0 deletions lib/config/development.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
(function() {

"use strict";

var express = require('express');

var app = this.app;
var config = this.app.config;

app.configure('development', function() {

config.environment = 'development';
config.debug = true;

app.use(express.errorHandler({
dumpExceptions: true,
showStack: true
}));

app.all('/', require('../controllers/config'));

});

}).call(global);
59 changes: 59 additions & 0 deletions lib/config/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
(function() {

"use strict";

var colors = require('colors');
var fs = require("fs");
var express = require("express");
var EventEmitter = require("events").EventEmitter;

var app = this.app;
var config = this.app.config = {};
var env = this.app.env = process.env;

app.event = new EventEmitter();

app.log = function log() {
var date = new Date();
var z = function(n) { if(parseInt(n) > 9) { return "" + n; } else { return "0" + n; } };
var args = [ ('[' + date.getFullYear() + '-' + z(date.getMonth() + 1) + '-' + z(date.getDate()) + ' ' + z(date.getHours()) + ':' + z(date.getMinutes()) + ':' + z(date.getSeconds()) + ']').white + '[saildata-server]'.yellow ];

for(var i in arguments) {
args.push(arguments[i]);
}

console.log.apply(console, args);
};

try {
//var pkg = fs.readFileSync('package.json', { encoding: 'utf8' });
// pkg = JSON.parse(pkg);

//config.settings = fs.readFileSync('settings.json', { encoding: 'utf8' });
//config.settings = JSON.parse(config.settings);

var pkg = require('../../package.json');

config.settings = require('../../settings.json');
config.name = pkg.name;
config.author = pkg.author;
config.version = pkg.version;
} catch(err) {
app.log('error parsing JSON', err);
config.settings = {};
config.name = "";
config.author = "";
config.vesion = -1;
}

app.configure(function() {

config.port = env.PORT || 3000;

app.use(express.logger());
});

require('./development');
require('./production');

}).call(global);
21 changes: 21 additions & 0 deletions lib/config/production.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
(function() {

"use strict";

var express = require('express');

var app = this.app;
var config = this.app.config;

app.configure('production', function() {

config.environment = 'production';
config.debug = false;

app.use(express.errorHandler());

app.all('/', require('../controllers/wifi'));

});

}).call(global);
12 changes: 12 additions & 0 deletions lib/config/staging.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
(function() {

"use strict";

var app = this.app;
var config = this.app.config;

app.configure('staging', function() {
config.environment = 'staging';
});

}).call(global);
15 changes: 15 additions & 0 deletions lib/controllers/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
(function() {

"use strict";

var path = require('path');

var views = path.join(__dirname, './lib/views');
var app = this.app;
var config = this.app.config;

module.exports = function(req, res) {
res.json(config);
};

}).call(global);
9 changes: 9 additions & 0 deletions lib/controllers/wifi.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
(function() {

"use strict";

module.exports = function(req, res) {
res.json({ ssid: "", password: "" });
};

}).call(global);
52 changes: 52 additions & 0 deletions lib/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
(function() {

var express = require('express')
, colors = require('colors')
, http = require('http')
, EJSON = require('e-json')
, wsServer = require('ws').Server
, Multiplexer = require('./lib/Multiplexer')
, app = this.app = express()
, server = http.createServer(app)
;

// config
require('./config');

// start server
server.listen(app.config.port, function() {

app.wss = new wsServer({ server: server });

app.wss.broadcast = function(data) {
data = EJSON.stringify(data);
for(var i in this.clients) {
this.clients[i].send(data);
}
};

app.wss.on('connection', function(socket) {
app.log("New client connected".blue);
});

app.multiplexer = new Multiplexer();

app.multiplexer.on('change', function() {
app.log("Signal K has changed. Sending new data to any Consumers listening to the stream.".cyan);
app.wss.broadcast(app.multiplexer.retrieve());
});

app.event.emit('server ready', { address: '127.0.0.1', port: app.config.port });
app.event.emit('socket ready', { address: '127.0.0.1', port: app.config.port });
app.log('Server ready and listening on 127.0.0.1:' + app.config.port);
app.log('Socket ready and listening on 127.0.0.1:' + app.config.port);

process.nextTick(function() {
require('./providers');
});
});

// export
module.exports = this.app;

}).call(global);
57 changes: 57 additions & 0 deletions lib/lib/Multiplexer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
var colors = require("colors");
var EventEmitter = require("events").EventEmitter;
var _ = require("lodash");
var util = require("util");

function Multiplexer() {
this.lastSignalK = null;
this.signalK = null;
}

util.inherits(Multiplexer, EventEmitter);

Multiplexer.prototype.add = function(data) {
var self = this;

if(this.signalK !== null) {
// Clone current signalK into lastSignalK
this.lastSignalK = _.clone(this.signalK, true);
}

process.nextTick(function() {
if(self.signalK !== null) {
self.signalK = _.merge(self.signalK, data);
} else {
self.signalK = _.merge({}, data);
}

if(!self.hasChanged()) {
self.emit('change');
}
});
};

Multiplexer.prototype.retrieve = function() {
return _.clone(this.signalK, true);
};

Multiplexer.prototype.hasChanged = function() {
if(this.signalK === null) return false;
if(this.lastSignalK === null) return true;

return !(_.isEqual(this.signalK, this.lastSignalK));
};

Multiplexer.prototype.log = function() {
var date = new Date();
var z = function(n) { if(parseInt(n) > 9) { return "" + n; } else { return "0" + n; } };
var args = [ ('[' + date.getFullYear() + '-' + z(date.getMonth() + 1) + '-' + z(date.getDate()) + ' ' + z(date.getHours()) + ':' + z(date.getMinutes()) + ':' + z(date.getSeconds()) + ']').white + ('[multiplexer]').yellow ];

for(var i in arguments) {
args.push(arguments[i]);
}

console.log.apply(console, args);
};

module.exports = Multiplexer;
101 changes: 101 additions & 0 deletions lib/lib/Provider.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
var _ = require('lodash')
, colors = require('colors')
, uuid = require('node-uuid')
, fork = require('child_process').fork
, path = require('path')
;

function Provider(provider, streamFn, debug) {
// Provider information
this.debug = !!debug;
this.name = '';
this.id = '';
this.identity = null;
this.fork = null;
this._to = null;
this.sleep = 1000;
this.streamFn = streamFn;

this.init(provider);
}

Provider.prototype.init = function(provider) {
this.name = provider.toLowerCase().replace('provider-', '');
this.id = uuid.v4().toUpperCase();
this.start();
};

Provider.prototype.start = function() {
this.log('Starting new fork');

var self = this;

// CREATE FORK
this.fork = fork(path.join(__dirname, '../../providers/', this.name));

// SETUP DIFFERENT LISTENERS
this.fork.on('message', function() { self.handleMessage.apply(self, arguments); });
this.fork.on('error', function() { self.handleError.apply(self, arguments); });
this.fork.on('close', function() { self.handleClose.apply(self, arguments); });
this.fork.on('disconnect', function() { self.handleDisconnect.apply(self, arguments); });
this.fork.on('exit', function() { self.handleExit.apply(self, arguments); });
};

Provider.prototype.handleMessage = function(data) {
if(data !== null && typeof data === 'object' && typeof data.messageType === 'string' && data.payload !== null && typeof data.payload === 'object') {
if(this.debug) this.log('Received', data.messageType);

if(data.messageType.toLowerCase() === 'identity') {
this.identity = data.payload;
if(this.debug) this.log('Set identity:\n', this.identity);
}

if(data.messageType.toLowerCase() === 'data') {
this.streamFn(data.payload);
}
} else {
if(this.debug) this.log('Reveived invalid data', data);
}
};

Provider.prototype.handleError = function() {
if(this.debug) this.log('Provider send an error', arguments);
var self = this;
clearTimeout(this._to);
this._to = setTimeout(function() { self.start(); }, this.sleep);
};

Provider.prototype.handleClose = function() {
if(this.debug) this.log('Provider send close', arguments);
var self = this;
clearTimeout(this._to);
this._to = setTimeout(function() { self.start(); }, this.sleep);
};

Provider.prototype.handleDisconnect = function() {
if(this.debug) this.log('Provider send disconnect', arguments);
var self = this;
clearTimeout(this._to);
this._to = setTimeout(function() { self.start(); }, this.sleep);
};

Provider.prototype.handleExit = function() {
if(this.debug) this.log('Provider send exit', arguments);
var self = this;
clearTimeout(this._to);
this._to = setTimeout(function() { self.start(); }, this.sleep);
};

Provider.prototype.log = function() {
var date = new Date();
var z = function(n) { if(parseInt(n) > 9) { return "" + n; } else { return "0" + n; } };
var args = [ ('[' + date.getFullYear() + '-' + z(date.getMonth() + 1) + '-' + z(date.getDate()) + ' ' + z(date.getHours()) + ':' + z(date.getMinutes()) + ':' + z(date.getSeconds()) + ']').white + ('[provider-' + this.name + ']').yellow ];

for(var i in arguments) {
args.push(arguments[i]);
}

console.log.apply(console, args);
};

module.exports = Provider;
23 changes: 23 additions & 0 deletions lib/providers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
(function() {

var _ = require('lodash');
var Provider = require('./lib/Provider');

var app = this.app;
var config = this.app.config;
var providers = this.app.providers = {};

var streamFn = function() {
app.multiplexer.add.apply(app.multiplexer, arguments);
};

_.each(config.settings.providers, function(provider_name) {

// var debug = config.debug;
var debug = false;
var provider = new Provider(provider_name, streamFn, debug);
providers[provider.id] = provider;

});

}).call(global);
Empty file added lib/views/config.ejs
Empty file.
Empty file added lib/views/wifi.ejs
Empty file.
Loading

0 comments on commit e338aab

Please sign in to comment.