I am using the nodejs serialport module (https://npmjs.org/package/serialport) and I am having issues when I write to the serial port.
If I simply write to the port as shown below, the serial device never gets the command.
var serialport = require("serialport");
var sp = new serialport.SerialPort(serialPortPath);
sp.write("SYST:ADDR?\n");
However, if I use a setTimeout as shown below, then it seems to work?
var serialport = require("serialport");
var sp = new serialport.SerialPort(serialPortPath);
setTimeout(function(){sp.write("SYST:ADDR?\n")},1000);
FYI, the "serialPortPath" is set elsewhere in the code.
I am not sure what is going on... any ideas?
I think I got it figured out from the github (https://github.com/voodootikigod/node-serialport page... basically it looks like I was missing the "open" event as shown below:
serialPort.on("open", function () {
console.log("open");
serialPort.on("data", function(data) {
console.log("data received: " + data);
});
serialPort.write("SYST:ADDR?\n", function(err, results) {
console.log("err: " + err);
console.log("results: " + results);
});
});
Here is another approach which works very well and allows for dynamic addressing of a specific serial device. In my case I am only interested in connecting to the Numato device connected to our integrated system which is why I have the conditional logic in the list callback.
exports.testSerial = function(data) {
serialPort.list(function(err, ports) {
var port = {};
for(var i = 0; i < ports.length; i++) {
try {
if(typeof ports[i].manufacturer != 'undefined' && ports[i].manufacturer.includes("Numato")) {
port = ports[i];
}
} catch(err) {
console.dir(err);
}
}
// the port will be opened via the constructor of this call
var numato = new serial(port.comName, {baudrate : 19200}, function(err) {
if(err) {
return console.dir(err);
}
// by having the write call within the callback you can access it directly w/o using .on()
numato.write('relay ' + data.state + ' ' + data.channel + '\r', function(err) {
if(err) {
console.dir('error writing');
console.dir(err);
}
console.dir('serial message written');
numato.close();
});
});
return true;
});
}
Hope this helps someone in the future! For reference this is with library version 4.0.7.
Related
Hey uh I am having an issue and I think this is probably related to net.createserver.
The issue is that whenever the first client joins after that another second client joins, the first client can control the second client and then the first client disconnects because the socket(end) event gets triggered. Is it related to sockets or something or the server can't handle two connections? Please help
The code:
handleGame: function() {
console.log(log.success('The source is starting!'));
var server = net.createServer(function(socket) {
console.log('A client has connected' + "\r\n");
socket.setEncoding('utf8')
global.clientObjz = new client(socket);
game.addClient(clientObjz);
socket.on('data', function(data) {
data = data.toString().split('\0')[0];
console.log('Incoming data: ' + data + "\r\n")
if (data == "<msg t='sys'><body action='verChk' r='0'><ver v='153' /></body></msg>" | data == "<msg t='sys'><body action='rndK' r='-1'></body></msg>" | data.startsWith("<msg t='sys'><body action='login' r='0'>")) {
parseXml(data, function(err, result) {
var type = result.msg['$'].t,
action = result.msg.body[0]['$'].action;
var method = Game.xmlHandlers[type][action];
if (typeof Game[method] == 'function') {
Game[method](data, client);
}
});
}
var dataType = data.charAt(0);
if (dataType == '%') {
game.handleraw(data, clientObjz);
}
});
socket.on('end', function() {
game.removeClient(socket);
console.log('A client has disconnected');
});
socket.on('error', function(err) {
console.log(err);
});
});
server.listen(Game1, "localhost", function() {
console.log('Server is listening on port 6113');
});
}
//this code is another file as i am calling it by game.clients.push
addClient: function(client) {
if (client) {
self.clients.push(client);
}
}
Yes, it's a clubpenguin emulator
full code: https://github.com/dev3211/bingojs
You need to implement socket channels if you are doing this only with NodeJS net.createServer. If you want it simple, you could look for something using express.js, something like this: https://medium.com/factory-mind/websocket-node-js-express-step-by-step-using-typescript-725114ad5fe4
I attached my server code:
var net = require('net');
var sqlite3 = require('sqlite3').verbose();
var db = new sqlite3.Database('MyBBDD.db');
var prueba = '';
function get_kw_actual(nombre,callback){
stmt = db.prepare("SELECT kw_actual FROM usuarios WHERE usuario = ?");
stmt.bind(nombre);
stmt.get(function(error,row){
if(error){
throw err;
}
else{
if(row){
entero=row.kw_actual;
callback(entero);
}
else{
console.log("error");
}
}
});
}
var server = net.createServer(function(socket) {
console.log("Recibo peticion");
socket.on('data', function (data) {
get_kw_actual('Pepe',function(resultado){
console.log('resultado es: ' + resultado);
prueba = '' + resultado;
})
socket.write(prueba);
});
socket.on('close', function () {
console.log('Connection closed');
});
});
server.listen(1337, '192.168.1.101');
In my server, I receive a request, I call to my function "get_kw_actual" I get a number of my database and finally I respond with the result.
The problem is that it runs first "socket.write(prueba);" than:
stmt.get(function(error,row){
if(error){
throw err;
}
else{
if(row){
entero=row.kw_actual;
callback(entero);
}
else{
console.log("error");
}
}
});
So... the execution is not executed in the correct order and the result is not correct.
Somebody know how can I solve it?
Thanks in advance.
Best regards.
Node.js code runs asynchronously. The code in the callback get_kw_actual returns immediately but the callback will run at some later time, when the database operation has completed. What you want to do is put socket.write inside of the callback, like this:
socket.on('data', function (data) {
get_kw_actual('Pepe',function(resultado){
console.log('resultado es: ' + resultado);
socket.write(resultado);
})
});
Also note that you're using a global variable prueba in your code, which will get clobbered when you have multiple clients running against your server. Do not use global variables like this in node.
I'm trying to modularize my application and would like to emit different event to client on different js file. Sample code below shows that an event 'onlinestatus' will be fired from led.js. However I keep on getting the message 'Type Error: Cannot read property 'sockets' of undefined' whenever I try to emit the event from led.js. I suspect something could be wrong when I"m trying to export the io from /bin/www.
/bin/www
var server = http.createServer(app);
var io = require('socket.io').listen(server);
var connectedClientsNum = 0;
io.sockets.on('connection', function(socket) {
console.log("client connected!");
socket.on('disconnect', function() {
console.log("Client disconnected...");
console.log("Total Clients Connected: " + --connectedClientsNum);
})
});
...
module.exports = server;
module.exports.io = io;
led.js
var io = require('../bin/www').io;
...
function toggleLed(leds, err, callback) {
/* toggle the led value */
if (leds[0].value == 0) {
leds[0].value = 1;
leds[0].save(function(err) {
if (err) {
err("update led error");
}
else {
var person= {"status": "online"};
io.sockets.emit('onlinestatus', person);
callback("update led from 0 to 1 success");
}
});
}
else {
leds[0].value = 0;
leds[0].save(function(err) {
if (err) {
err("update led error");
}
else {
var person= {"status": "offline"};
io.sockets.emit('onlinestatus', person);
callback("update led from 1 to 0 success");
}
});
}
}
You should check the Docs at socket.io and check to see if there is actually still a socket.sockets.on() function still in the socket.io framework. I'm not sure if it is still there. If you must have it working, you could try changing versions of socket.io to 0.9, which would be where I think that would work.
I am using the SerialPorts module for nodejs and need to be able to open, write and read from a variable number of serial ports.
So what I am doing is to first create an array object for the serialPort instances, and then process them in a loop:
var serialport = require("serialport");
var SerialPort = serialport.SerialPort; // localize object constructor
var devs = ["/dev/tty.SerialPort","/dev/tty.HHW-SPP-1800-2-DevB"];
var ports = [];
for (var i = 0; i < devs.length; i++) {
console.log(devs[i]);
var port = new SerialPort(devs[i],{ baudrate:9600, parser: serialport.parsers.readline("\n") });
ports.push(port);
}
Then I have another function that I call periodically to read / write from the ports:
function minute(){
for (var i = 0; i < ports.length; i++) {
console.log(i);
ports[i].on("open", function (path) {
console.log('opened');
ports[i].write("Helo World\n", function(err,res) {
if(err) console.log('err ' + err);
console.log('results ' + res);
});
ports[i].on("data", function (data) {
console.log("here: "+data);
});
});
}
}
The problem is the minute() function executes, however it does not attempt to open or read / write to the ports.
What am I doing wrong ?? and is there a better way of doing this ??
There are a couple misconceptions at play here.
Firstly, you don't need to periodically poll your ports. Nodejs uses an event loop (more or less), to handle IO, and will do the polling for you. So all you need to do is setup the callbacks for the open event, one time for each port. In your code, it looks like you are readding the callback each time minute() is being called. That is not necessary.
Secondly, javascript doesn't have block scoping for variables. Instead you are inadvertently creating a closure, and your code is in error. In this following block:
for (var i = 0; i < ports.length; i++) {
ports[i].on("open", function (path) {
ports[i].write("Helo World\n", function(err,res) {
if(err) console.log('err ' + err);
console.log('results ' + res);
});
ports[i].on("data", function (data) {
console.log("here: "+data);
});
});
}
When your callback for ports.on is invoked, the value of i in ports[i].write and ports[i].on("data") isn't the value of i when the callback is setup, as you are expecting. Instead, because you have created a closure, the value of i isn't bound(set) until the callback is executed. In this example, everyone of your callbacks, i will be set to ports.length, which was the last evaluated value for i
I've created a plunkr that illustrates the problem with your for loop.
One way to fix this problem is to use an anonymous method, and bind the value i to a new local variable. In the code below, (function(index){})(i); executes immediately, and binds the value index to the appropriate value of i.
ports[i].on("open", function (path) {
(function(index) {
ports[index].write("Helo World\n", function(err,res) {
if(err) console.log('err ' + err);
console.log('results ' + res);
});
ports[index].on("data", function (data) {
console.log("here: "+data);
});
})(i);
});
You could also instead pull that method out into a separate function. setupHandlers() executes immediately, and is bound to the proper port.
for (var i = 0; i < ports.length; i++) {
setupHandlers(ports[i]);
}
function setupHandlers(port) {
port.on("open", function (path) {
ports.write("Helo World\n", function(err,res) {
if(err) console.log('err ' + err);
console.log('results ' + res);
});
ports.on("data", function (data) {
console.log("here: "+data);
});
});
}
I have an assignment to write an http server in node.js, which is why I can't use the http module, as you'll soon see. Anyway, I need to be able to listen to both GET and POST requests. The way I understand it GET only fires data event, and post fires data and end. Here's my code:
function Server(resourceMap, rootFolder) {
this.resourceMap = resourceMap;
this.rootFolder = rootFolder;
function connectionHandler(socket) {
console.log('server connected');
console.log('CONNECTED: ' + socket.remoteAddress +':'+ socket.remotePort);
socket.setEncoding('utf8');
socket.on('data',function(data) {
var re = new RegExp("^( *)(GET)", "i");
if (data.match(re) != null) {
console.log("Handling GET request");
router.route(data,socket,handle,resourceMap,rootFolder);
}
else {
(function() {
var postData = data;
socket.on('data',function(data) {
postData += data;
});
console.log(postData);
socket.on('end',function(postData) {
console.log("END");
console.log("Handling POST request");
router.route(postData,socket,handle,resourceMap,rootFolder);
});
});
}
});
}
this.server = net.createServer(connectionHandler);
this.port = undefined;
this.startServer = function(port) { //Maybe change backlog for security reasons
this.port = port;
this.server.listen(port, function() { //'listening' listener add handle object here
console.log('server bound');});
}
}
GET requests works just fine. With POST It doesn't even enter the anonymous function.
Any ideas why and how I can solve it?
EDIT: solved - I defined the function but didn't call it :)
If you have any comments about my design I'd love to hear, as I am new to node.js and JavaSCript
Thanks
Common mistake: defined a function but did not call.
You can either:
Get rid of the function keyword after else for regex
Or add () after function (which is more recomended)