node.js bridgecode

This code runs under Linux on a Raspberry Pi 3B single board computer. It acts as a server to the user's Web page client and as a client to the cart's server. It also supplies the cart with a 'keep-alive' character once every 250 milliseconds without which the cart will shut down in order to avoid 'run away' if the communications link is broken.




//  Browser and socket cart control server & client (IEC, Nov. 19)
//  (Supported by a Linux Raspberry Pi 3B)
//
//  Works in conjunction with client Web page v.19/12/19 and ...
//  with Arduino cart server software 'Kartibot_PA09_SC.ino'.
//  This is therefore a server to the page and a client to the cart.
//  Needs Node.js, npm and ws installed.
//  Started by 'node servecartp1.js' at the server command prompt ...
//  or with call to 'start-server.sh' in '/etc/rc.local' during boot.
//  Note.  When working with command prompt kill any background ...
//  running version with 'sudo pkill -f node'.
//  This version uses global variables to pass data between ... 
//  channels to avoid the complications of nesting objects.

// --------------------------------------------------------------
//  Declarations and global variables

//  For connection of this server to client
var WebSocketServer = require('ws').Server;
    myport = 8094;
    wss = new WebSocketServer({port: myport});

//  For transfer of data from client to cart
var client2cart = '';

//  For transfer of data from cart to client
var cart2client = '';

var cartwritecount = 0;  // For long term cart keep-alive

var startup = 0;  // For first time detection

// ------------------------------------------------------

//  Procedure.
//  Establishes a send/receive event loop with the cart.
//  To prevent 'run-away' the cart will shut down if it ...
//  does not recieve regular transmissions from a client.

//  Connect to client and collect data
wss.on('connection', function(ws) {
	startloop(ws);
	console.log('CONNECTED TO CLIENT');
	
	 ws.on('message', function(cdata) {

		client2cart = cdata;

	});

});


//  Connect to cart and start command loop
function startloop(ws) {

	var s = require('net').Socket();

	//  Connect to the cart
	s.connect(23, '192.168.2.5', function() {

		ws.send(JSON.stringify('Connected via server to cart.'));		

		s.write('&');  // Stimulate initial response from cart

	});


	// Collect response from cart
	s.on('data', function(fromcart) {

		s.pause();  // Stop reception event emissions

		if(fromcart.indexOf('&') == -1 && fromcart.indexOf('C') == -1) {
			ws.send(JSON.stringify(fromcart.toString()));
		}

		cartwrite(s);  // Send instructions to cart
		
		// Restart reception event emissons after n milliseconds
		setInterval(function(){ s.resume(); }, 250); // was 500

	});

        
        // Trap reception errors 
	s.on('error', function(carterror) {

		ws.send(JSON.stringify("The cart is not ready"));

	});	

}

// Transmits commands and 'keep-alive' chars to cart
function cartwrite(s) {

	if(client2cart == '') {
		s.write('&'); // Short term keep-alive character
	}	
	else {
		s.write(client2cart);  // Command string from client
		
		client2cart = '';
	}

	cartwritecount ++;
	if(cartwritecount > 120) {   // once every 30 secs.
		cartwritecount = 0;
		s.write('C`O`N^\r\n');  //Long term (avoid battery check) keep-alive
		
	}

}


/*  END OF CODE  */