Capture Data from TCP stream using NodeJS

I work on a wireless sensor network that utilizes several different Node servers to transmit, receive, decode and validate radio sensor data from hundreds of radios deployed in Central and South Florida.

The individual radio transmitters connected to consumer equipment communicate with a data receiver high atop a radio tower in downtown Orlando. The receiver's server apps are built on Node and Express.

This project has grown over the past 6 months and is expanding to include a new cellular receiver. The current app setup uses Express to route system events to event handlers which in turn perform some operation on the received sensor data. Those operations include decoding the message, storing the raw sensor data or syncing with the gateway. The one caveat here is that the cellular receiver is a simple TCP stream. We won't have an event handler since there is no event.

Instead of an event handler, the app needs to just listen on a defined port for any traffic streaming into the server app. In order to continue to utilize the server app's dependencies in Express, I decided the easiest approach would be to create a separate server app that will run in parallel with the standard data receiver.

This will allow me to bypass Express' routing rules and have the server accept incoming radio sensor data on a IP/port.

Starting up a new server is Node is a snap.

var net = require('net');  
var nconf = require('nconf');  
var decoder = require('./decoder.js');  
var moment = require('moment');  
var mysql = require('mysql');  
var log = require('util').log;

var portNumber = process.argv[2];  
var timer;  
var timeout = 5000;

nconf.argv()  
   .env()
   .file({file" 'config.json'});


var server = net.createServer(function(c) {

  server.getConnections(function(error, count) {
    if (count == 1) {
      console.log('The server has 1 active connection.');
    } else {
      console.log('The server has ' + count + ' active connections.');
    }
  });

  c.on('connect', function() {
    console.log('client connected');
  });

  c.on('end', function() {
    console.log('client disconnected');
  });

  c.on('data', function(data) {
    var res = decoder.decodeBuffer(data);
    /* decode sensor data and insert to the database  */ 
  });

  c.on('error', function(err) {

    if (err.code == 'ENOTFOUND') {
      console.log('[ERROR] No devide found at this address.');
    }

    if (err.code == 'ECONNREFUSED') {
      console.log('[ERROR] Connection refused, please check the IP address.');
    }
  });

  time = setTimeOut(function() {
    console.log('[ERROR] The client has exceeded the timeout value: ' + timeout);
    return;
  }, timeout);

  server.listen(portNumber, function() {
    address = server.address();
    console.log('The server is bound on %s', address);
  });
});

While I left the decoding sequence out of the sample code, you can get the idea of how this simple Node NET server can listen for and receive data in the stream buffer. Once the stream is received, the data method is called:

c.on('data', function(data) {  
  /* act on the received data */
});

The buffer data is then decoded and our sensor data is extracted from our data payload. The decoded raw sensor data is then written to MySQL, which syncs the data to the gateway to be consumed by the dealer portal.

There are a log of moving parts to this wireless sensor project; but Node makes it super easy to create new system features that keeps the business growing and the technology used to make the project a success, well, streaming :-)

I will explore more of NodeJS' features in upcoming posts.

Craig Derington

Veteran full stack web dev focused on deploying high-performance, responsive, modern web applications using Python, NodeJS, Django, Flask, MongoDB and MySQL.

comments powered by Disqus