How to capture database connection state or ping connection? - javascript

Using MySql driver for Node.js, here is my ping method:
function ping(){
connection.connect(function(err) {
if (err) {
console.error('error connecting: ' + err.stack);
return false;
}
console.log('connection authenticated: ' + (connection.state == "authenticated"));
console.log('connected as id ' + connection.threadId);
});
console.log("connection: " + connection.state);
return (connection.state == "authenticated");
}
Apparently, this node-mysql library does not have a native Ping method. I thought this would serve well in its stead. However, I am seeing the following issue in the console:
debugger listening on port 53213
connection: disconnected
Fri, 26 Dec
2014 14:12:38 GMT RazorJS Express server listening on port 3000
connection authenticated: true
connected as id 17
It seems that the connection state is being logged and returning false before the connection is actually open. Maybe this is being executed async? How can I get this to function synchronously?

You have written the below outside the callback on connection.connect function.So before your connection.connect executes its callback ,the below code gets executed(async nature of node.js) and therefore its first consoled as disconnected.
console.log("connection: " + connection.state);
return (connection.state == "authenticated");
The above should be inside the callback.
function ping() {
connection.connect(function(err) {
if (err) {
console.error('error connecting: ' + err.stack);
return false;
}
console.log('connection authenticated: ' + (connection.state == "authenticated"));
console.log('connected as id ' + connection.threadId);
console.log("connection: " + connection.state);
return (connection.state == "authenticated");
});
}

Related

Loopback/Strongloop failed with ssh2 function callback Error: write ECONNABORTED

I want to have a REST API that would return in web browser some cisco router CLI output from Cisco CLI command inputs via REST request using ssh2 and loopback.
I can't figure it out because of these errors.
The code below will run a few milliseconds returning some correct and expected output but then breaks the loopback instance at server side will break/stop.
Error encountered:
C:\LOCAL_APPS\Loopback\filedir\node_modules\async\dist\async.js:955
if (fn === null) throw new Error("Callback was already called.");
^
Error: Callback was already called.
at C:\LOCAL_APPS\Loopback\filedir\node_modules\async\dist\async.js:955:32
at C:\LOCAL_APPS\Loopback\filedir\node_modules\async\dist\async.js:3871:13
at interceptInvocationErrors
(C:\LOCAL_APPS\Loopback\filedir\node_modules\strong-remoting\lib\remote-
objects.js:713:22)
at C:\LOCAL_APPS\Loopback\filedir\node_modules\loopback-phase\node_modules\async\lib\async.js:154:25
at C:\LOCAL_APPS\Loopback\filedir\node_modules\loopback-phase\node_modules\async\lib\async.js:154:25
at C:\LOCAL_APPS\Loopback\filedir\node_modules\loopback-phase\node_modules\async\lib\async.js:154:25
at C:\LOCAL_APPS\Loopback\filedir\node_modules\strong-remoting\lib\remote-objects.js:679:7
at C:\LOCAL_APPS\Loopback\filedir\node_modules\strong-remoting\lib\http-context.js:305:7
at callback (C:\LOCAL_APPS\Loopback\filedir\node_modules\strong-remoting\lib\shared-method.js:
Stream :: close :: code: 0, signal: undefined
events.js:183
throw er; // Unhandled 'error' event
^
Error: write ECONNABORTED
at _errnoException (util.js:1024:11)
at Socket._writeGeneric (net.js:767:25)
at Socket._write (net.js:786:8)
at doWrite (_stream_writable.js:387:12)
at writeOrBuffer (_stream_writable.js:373:5)
at Socket.Writable.write (_stream_writable.js:290:11)
at Socket.write (net.js:704:40)
at SSH2Stream.ondata (_stream_readable.js:639:20)
Under common/models/device.js:
'use strict';
module.exports = function(Device) {
Device.getIPInterfaceBrief = function(ipaddr,cb){
var filter = {
include:{
relation: 'infosheet',
scope:{
fields:['data']
}
}
}
var Client = require('ssh2').Client;
var conn = new Client();
conn.on('ready', function() {
console.log('Client :: ready');
conn.exec('show ip int br', function(err, stream) {
if (err) throw err;
stream.on('close', function(code, signal) {
console.log('Stream :: close :: code: ' + code + ', signal: ' + signal);
conn.end();
}).on('data', function(data) {
cb(null,"data: " + 'done') //or cb(null,"data: " + data)
console.log('STDOUT: ' + data);
}).stderr.on('data', function(data) {
console.log('STDERR: ' + data);
});
});
}).connect({
host: ipaddr,
port: 22,
username: 'routerusername',
password: 'passwordhere'
});
console.log("check 1");
};
Device.remoteMethod('getIPInterfaceBrief',{
description: "Returns the brief interface information of a device",
accepts:{
arg:'ipaddr',
type: 'string',
required: false
},
http:{
path:'/:ipaddr/getIPInterfaceBrief',
verb: 'get'
},
returns:{
arg:'interfaceinfo',
type:'any'
}
});
}; //module.exports
REST TEST URL:
http:// localhost:3000/api/adevices/some-ip-here/getIPInterfaceBrief
Error encountered after few seconds API responded the get REST request:
I temporarily added some try catch statement it worked somehow.
I think loopback is not part of the issue.
Hope you have better fix since the code works on other machines like Linux system but for Cisco routers have some problem with the line "conn.end".
Added try and catch to capture the errors..
if (err) throw err;
stream.on('close', function(code, signal) {
console.log('Stream :: close :: code: ' + code + ', signal: ' + signal);
try {
conn.end();
}catch (err){
console.log("error occured",err);
}
}).on('data', function(data) {
console.log('STDOUT: ' + data);
}).stderr.on('data', function(data) {
console.log('STDERR: ' + data);
});
My test did capture the error see here

i want to send a CTRL + C command to client how can i acheive this in NodeJS?

My Code Looks Like this
var Client = require('ssh2').Client;
var fs=require('fs');
var conn = new Client();
conn.on('ready', function() {
console.log('Client :: ready');
conn.shell('xtail', function(err, stream) {
stream.write('xtail\n\r');
if (err) throw err;
stream.on('close', function(code, signal) {
console.log('Stream :: close :: code: ' + code + ', signal: ' + signal);
conn.end();
}).on('data', function(data) {
// stream.stdin.write('?');
console.log('hey');
console.log('STDOUT: ' + data);
fs.appendFile('D:\\Breme\\As1.txt',data,function(err){
if(err)
{
console.log(err);
}
//console.log('file saving..')
});
// setTimeout(function(){
// process.exit(1);
// }, 20000);
}).stderr.on('data', function(data) {
console.log('STDERR: ' + data);
conn.destroy();
});
});
}).connect({
host: '10.214.14.15',
port: 22,
username: 'bwadn',
password: 'bwain'
});
after connecting to server I am downloading the file but I want to send 'Ctrl+C' command from client, so that it stops receiving data
Can anyone please help me in solving this, As i am new to NodeJS I need your support in solving this...thanks
Most reliable way in this particular case, since you are using a variant of tail in your shell, is to use
stream.write('\x03'); //send ctrl+c
you would need to send it when you know you don't need xtail output anymore. It is beyond the scope of this question to discuss the means, but setTimeout is definitely not a good idea.
Alternative (preferred) method:
stream.signal('INT')
and for other uses see Ssh2 Channel API

net.socket.setTimeout does not work with async.eachOfSeries

I am having this issue were if I am not able to connect to a host, Nodejs stalls. The weird part is I had this working with async.eachSeries when it was a array and the port was static. Does anyone know why?
client = new net.Socket;
hosts = {'google.com': '443', 'yahoo.com': '80','msn.com': '444'};
client.setTimeout(1000, function () {
console.log("Timeout has occurred")
});
async.eachOfSeries(hosts, function(port,host,callback) {
client.connect(port, host, function() {
console.log('Connected to ' + host + " on port " + port);
client.destroy();
callback();
});
});
client.on('timeout', function() {
console.log('client has timed out');
client.destroy(); // kill client after server's response
});
Thank you,
John
msn.com connection on port 444 fails and and the last 'callback' (after successful connect) is never called- which is why node stalls.
Check the following code which solves this (notice msn call is now the first one and just times out- I feel it's better for understating the flow).
var async = require('async');
var net = require('net');
hosts = { 'msn.com': '444', 'google.com': '443', 'yahoo.com': '80' };
async.eachOfSeries(hosts, function (port, host, callback) {
client = new net.Socket;
client.setTimeout(1000, function () {
console.log("Timeout has occurred")
});
client.connect(port, host, function () {
console.log('Connected to ' + host + " on port " + port);
client.destroy();
callback();
}).on('timeout', function () {
console.log('client has timed out');
client.destroy();
callback();
});
});

node js :Can\'t set headers after they are sent

How to send the response properly. I like to move to another page after FTP and Telnet sessions.
Even tried using res.redirect function too. While using res.redirect, i commented window.location= "SaveRedirect"; line, in javascript of html page. Even then, I get the same error.
Here presenting the code snippet,
the javascript code in html
IPData ={
"DeviceIpAddr": "192.168.1.2"
};
function processSave() {
$.post("PostSave", IPData, function(data) {
window.location= "SaveRedirect";
});
return true;
}
node js code snippet
app.get('/SaveRedirect', function (req, res) {
res.sendFile( __dirname + "/" + "Page2.htm" );
})
var bodyParser = require('body-parser');
var testJsonEncoder = bodyParser.json();
urlEncoded = bodyParser.urlencoded({ extended: true });
app.post('/PostSave', testJsonEncoder,urlEncoded, function(request, response){
var LoginData = JSON.stringify(request.body, null, 4);
console.log(LoginData);
FormDataObj = JSON.parse(LoginData);
gDeviceIpAddress = FormDataObj.DeviceIpAddr;
console.log("IP Address" + gDeviceIpAddress);
console.log("FTP to linux box...");
ftpFile(gDeviceIpAddress, "PUT", "temp_data.json", response);
console.log("FTP temp_data file to linux box... Done!");
TelnetLinux(gDeviceIpAddress);
console.log("Telnet to linux box... Done!");
response.send("just to send response");
//response.json(LoginData);
});
function ftpFile(ftpIPAddr, operation, filename, resp) {
console.log("ftpIPAddr = " + ftpIPAddr);
ftpConfig.host = ftpIPAddr;
// Handle error
ftpClient.on("error", function (err) {
console.log(" - ERROR HANDLE - \n");
console.log(err);
resp.send("FAIL: " + err.message);
ftpClient.end();
});
// Handle error
ftpClient.on("ready", function () {
console.log("Connected....\n");
if(operation == "GET") {
console.log("filename : " + filename);
ftpClient.get(filename, function(err, stream) {
if (err)
{
resp.send("FAIL: " + err.message + " - " + filename);
ftpClient.end();
//throw err;
}
else {
stream.once('close', function() { ftpClient.end(); });
stream.pipe(fs.createWriteStream('test_data.json'));
resp.send("SUCCESS: file received");
ftpClient.end();
}
});
}
if(operation == "PUT") {
ftpClient.put(filename, filename, function(err) {
if (err) {
resp.send("FAIL: " + err.message + " - " + filename);
ftpclient.end();
throw err;
}
else {
resp.send("SUCCESS: file sent");
ftpClient.end();
}
});
}
});
ftpClient.connect(ftpConfig);
}
function TelnetLinux(deviceIPAddr) {
var telnetParams = {
host: deviceIPAddr,
port: 23,
username: "webtest",
password: "test123",
shellPrompt: '$',
timeout: 1500,
// removeEcho: 4
};
cmd = "ls";
console.log("Telnet Address : " + deviceIPAddr);
telnetClient.on('ready', function(prompt) {
telnetClient.exec(cmd, function(err, response) {
//console.log(response);
console.log("Cmd executed !");
});
});
telnetClient.on('timeout', function() {
console.log('telnet socket timeout!')
telnetClient.end();
});
telnetClient.on('close', function() {
console.log('telnet connection closed');
});
telnetClient.connect(telnetParams);
}
Error :
c:\WebTest>node webapp.js
Example app listening at http://:::8081
IP Address192.168.1.2
FTP to linux box...
ftpIPAddr = 192.168.1.2
FTP temp_data file to linux box... Done!
Telnet Address : 192.168.1.2
Telnet to linux box... Done!
Cmd executed !
telnet socket timeout!
telnet connection closed
Connected....
_http_outgoing.js:346
throw new Error('Can\'t set headers after they are sent.');
^
Error: Can't set headers after they are sent.
at ServerResponse.OutgoingMessage.setHeader (_http_outgoing.js:346:11)
at ServerResponse.header (c:\WebTest\node_modules\express\lib\response.js:719:10)
at ServerResponse.send (c:\WebTest\node_modules\express\lib\response.js:164:12)
at c:\WebTest\webapp.js:222:11
at Object.cb (c:\WebTest\node_modules\ftp\lib\connection.js:1017:13)
at Parser.<anonymous> (c:\WebTest\node_modules\ftp\lib\connection.js:117:20)
at emitTwo (events.js:100:13)
at Parser.emit (events.js:185:7)
at Parser._write (c:\WebTest\node_modules\ftp\lib\parser.js:59:10)
at doWrite (_stream_writable.js:301:12)
at writeOrBuffer (_stream_writable.js:287:5)
at Parser.Writable.write (_stream_writable.js:215:11)
at Socket.ondata (c:\WebTest\node_modules\ftp\lib\connection.js:273:20)
at emitOne (events.js:90:13)
at Socket.emit (events.js:182:7)
at readableAddChunk (_stream_readable.js:153:18)
This happens when you try to do res.send (or response.send) multiple times in the same call. I believe it has to do with this bit of code:
app.post('/PostSave', testJsonEncoder, urlEncoded, function(request, response) {
var LoginData = JSON.stringify(request.body, null, 4);
console.log(LoginData);
FormDataObj = JSON.parse(LoginData);
gDeviceIpAddress = FormDataObj.DeviceIpAddr;
console.log("IP Address" + gDeviceIpAddress);
console.log("FTP to linux box...");
ftpFile(gDeviceIpAddress, "PUT", "temp_data.json", response);
console.log("FTP temp_data file to linux box... Done!");
TelnetLinux(gDeviceIpAddress);
console.log("Telnet to linux box... Done!");
response.send("just to send response");
//response.json(LoginData);
});
You're doing a response.send at the end of this function, and again in ftpFile()
Since you are sending response multiple times in app.post("/Postsave" and function ftpFile for the same request, you get this error.
To resolve this, I would suggest you to send the result(or error) from the ftpfile back to the app.post(i.e., through callback) and then based on the result or error send the response from the app.post function.

node.js wait for events on variable length array type

so I am writing a small application which exposes the serial port to a web service.
The client is allowed to open ports and the server keeps track on what ports are opened.
I am a complete newbie to javascript so please also point out any other errors you can see in my code!
anyway I have websockets to pass messaged between the client and the server.
There is a ser_con event which instructs the server to open a new connection to a serial port. This also appends serialport object to an array so I can later refer to it.
var ser = []
...
socket.on('ser_con', function(d) {
console.log('connect event')
sp = new SerialPort.SerialPort(d.name, {
baudrate: d.baudrate,
databits: d.databits,
stopbits: d.stopbits,
parity: d.parity,
buffersize: d.buffersize,
parser: SerialPort.parsers.raw
},false);
sp.open(function (err) {
if (err) {
console.log('Error connecting to port: ' + d.name + ', error: ' + err);
socket.emit('ser_err', 'Error connecting to port: ' + d.name + ', error: ' + err);
} else {
console.log('connected to serial port ' + d.name);
data = {
name: d.name,
b:'connected to serial port ' + d.name + '\n'
}
socket.emit('data', data);
ser.push({'name':d.name,'sp':sp})
}
})
});
So once connection is succesfull I append the name of the port and the instance of the serialport object to the ser array.
The problem I am having is on how I can listen to events on all the serialports instances
I tried doing this but it doesn't work, I assume this isn't allowed since the for loop isn't an event by itself. I have no idea how to solve this though since...
for (var i=0; i < ser.length; i++){
ser[i].sp.on('data', function(d) {
console.log('recieved data on port ' + ser[i].name)
data = {
name: ser[i].name,
b: d
}
socket.emit('data', data);
});
}
any help is appreciated.
You are using for iterator variable in the callbacks. This is a common javascript mistake. To fix this:
for (var j=0; j < ser.length; j++){
(function(i){
ser[i].sp.on('data', function(d) {
console.log('recieved data on port ' + ser[i].name)
data = {
name: ser[i].name,
b: d
}
socket.emit('data', data);
});
}(j))
}
I don't know where in your code you are running this for loop. But if you are not properly handling this you might end up binding multiple callbacks to the same serial port object. I recommend to bind events after opening the port:
...
sp.open(function (err) {
if (err) {
console.log('Error connecting to port: ' + d.name + ', error: ' + err);
socket.emit('ser_err', 'Error connecting to port: ' + d.name + ', error: ' + err);
} else {
console.log('connected to serial port ' + d.name);
data = {
name: d.name,
b:'connected to serial port ' + d.name + '\n'
}
socket.emit('data', data);
ser.push({'name':d.name,'sp':sp})
//listen 'data' event here
//you have access to both 'd' and 'socket' variable here
sp.on('data', function(data) {
console.log('recieved data on port ' + d.name)
data = {
name: d.name,
b: data
}
socket.emit('data', data);
});
}
})

Categories

Resources