API Docs for: 1.0.0
Show:

File: LADS/telemetry/server.js

/**
 * A basic telemetry server. Should probably be hooked up with a DB.
 * @class Telemetry
 * @constructor
 */

(function Telemetry() {
	// node modules
	var http = require('http'),
	    fs   = require('fs'),
	    qs   = require('querystring');

	// some constants
	var PORT = 9999,
		NOT_AVAIL = "_",
	    MAX_BODY_LENGTH = Math.pow(10,6),
	    WRITE_DATA = writeTDataToFile,
	    READ_DATA = readTDataFromFile,
	    LOG_FILE_PATH = 'telemetry_log.txt';

	// create server
	http.createServer(function (request, response) {
		switch(request.method.toLowerCase()) {
			case 'post':
				handlePost(request, response);
				break;
			case 'get':
				handleGet(request, response);
				break;
			default:
				console.log('======= UNSUPPORTED REQUEST TYPE =======');
				console.log('sent at: '+(new Date().toString()));
		}
	}).listen(PORT, '127.0.0.1');

	/**
	 * Handles a post request to the server. Generally, writes data to log file.
	 * In the future, this should probably log data in a database.
	 * @method handlePost
	 * @param {Object} request      the http request sent to the server
	 * @param {Object} response     a response object we'll write to and return
	 */
	function handlePost(request, response) {
		var requestBody = '',
			parsedBody,
			date = new Date(),
			printData,
			tdata; // telemetry data

		// read in data from request as it becomes available
		request.on('data', function(dataChunk) {
			requestBody += dataChunk;

			// if too much data, could be malicious, cut it off. our data will be small anyway...
			if(requestBody.length > MAX_BODY_LENGTH) {
				request.connection.destroy();
			}
		});

		// when all data is read
		request.on('end', function() {
			parsedBody = qs.parse(requestBody); // parse body to js object

			// telemetry data object
			tdata = {
				time_stamp: date.getTime(),                         // milliseconds since 1970
				type: parsedBody.ttype || NOT_AVAIL,                // type of telemetry request
				ip: request.connection.remoteAddress || NOT_AVAIL,  // ip of computer that generated request
				tagserver: parsedBody.tagserver || NOT_AVAIL,       // TAG server to which computer is connected
				browser: parsedBody.browser || NOT_AVAIL,           // browser
				platform: parsedBody.platform || NOT_AVAIL,         // platform (e.g., Mac)
				time_human: date.toString()                         // human-readable time
			};

			WRITE_DATA(tdata);

			response.writeHead(200, {
				'Content-Type': 'text/plain',
				'Access-Control-Allow-Origin': '*'
			});
			response.end(); // done creating response, don't need to send back any data
		});
	}

	/**
	 * Handles a get request to the server. SHOULD get data from server, return it to client
	 * for data viz or analysis.
	 * @method handleGet
	 * @param {Object} request          the http request to the server
	 * @param {Object} response         the response we'll send back to the client
	 */
	function handleGet(request, response) {
		var requestBody = '',
			parsedBody,
			date = new Date(),
			tdata; // telemetry data

		// read in data from request as it becomes available
		request.on('data', function(dataChunk) {
			requestBody += dataChunk;

			// if too much data, could be malicious, cut it off. our data will be small anyway...
			if(requestBody.length > MAX_BODY_LENGTH) {
				request.connection.destroy();
			}
		});

		// when all data is read
		request.on('end', function() {
			parsedBody = qs.parse(requestBody); // parse body to js object
			console.log("about to call READ_DATA");
			READ_DATA(response);
		});
	}

	/**
	 * Writes telemetry data to a log file (specified by LOG_FILE_PATH).
	 * Set the global WRITE_DATA = writeTDataToFile to log data in this way.
	 * @method writeTDataToFile
	 * @param {Object} tdata     the telemetry data object to stringify and write to file
	 */
	function writeTDataToFile(tdata) {
		fs.writeFile(LOG_FILE_PATH, JSON.stringify(tdata)+',', {flag: 'a'}, function(err){
			if(err) {
				console.log('err: '+err);
			} else {
				console.log('interaction successfully written to log:');
				console.log('       time: '+tdata.time_human);
				console.log('       type: '+tdata.type);
				console.log('');
			}
		});
	}

	/**
	 * Reads telemetry data from a file (specified by LOG_FILE_PATH) and
	 * returns it to client in a response.
	 * Set the global READ_DATA = readTDataFromFile to read data in this way.
	 * @method readTDataFromFile
	 * @param {Object} tdata    the response we will eventually send back
	 */
	function readTDataFromFile(response) {
		fs.readFile(LOG_FILE_PATH, {encoding: 'utf8'}, function(err, data){
			var i,
				arr;
			
			response.writeHead(200, {
				'Content-Type': 'text/plain',
				'Access-Control-Allow-Origin': '*'
			});

			if(err) {
				console.log('err: '+err);
			} else {
				if(data.charAt(data.length-1) === ',') {
					data = data.slice(0, data.length-1); // remove trailing comma
				}
				arr = JSON.parse('['+data+']'); // arr is an array of telemetry data objects
				for(i=0;i<arr.length;i++) { // this isn't very efficient...should use db queries
					;
				}

				console.log('retrieving telemetry data succeeded:');
				console.log('       time: '+(new Date()).toString());
				console.log('');

				response.write(JSON.stringify(arr));
			}

			response.end(); // done creating response
		});
	}

	console.log('Telemetry server running at http://127.0.0.1:'+PORT+'/');
})();