AMQP Connection Closed certain time interval with node js - node.js

I tried out last 3 days with the below issue. Kindly help me to resolve the issue,
>Error: Unexpected close
at succeed (/usr/local/lib/node_modules/amqplib/lib/connection.js:259:13)
at onOpenOk (/usr/local/lib/node_modules/amqplib/lib/connection.js:241:5)
at /usr/local/lib/node_modules/amqplib/lib/connection.js:160:32
at /usr/local/lib/node_modules/amqplib/lib/connection.js:154:12
at Socket.recv (/usr/local/lib/node_modules/amqplib/lib/connection.js:480:12)
at Socket.g (events.js:180:16)
at Socket.EventEmitter.emit (events.js:92:17)
at emitReadable_ (_stream_readable.js:407:10)
at emitReadable (_stream_readable.js:403:5)
at readableAddChunk (_stream_readable.js:165:9)
I am using amqplib + node js. Whenever i started the server i got the above error with a time interval. Maximum it will occurs at 5 mins interval.
amqplib = amqplib.connect('amqp://'+rabit_host).then(function(conn)
{
amqpconnection = conn;
});
io.sockets.on('connection', function(client)
{
client.on('receivemsg', function(arg)
{
amqpconnection.createConfirmChannel().then(function(channelObjSuccess)
{
channelObjSuccess.assertQueue(queue_name,{durable:false,autoDelete:true});
client.assignObj = channelObjSuccess;
channelObjSuccess.consume(queue_name, function(msg)
{
var encodemsg = msg.content.toString();
var json_msg = JSON.parse(encodemsg);
client.emit('chatrecive',json_msg);
}).then(function(){
console.log("Receive Consiuume Close");
});
});
});
client.on('loginentry', function(arg)
{
amqpconnection.createConfirmChannel().then(function(channelObjSuccess) {
channelObjSuccess.assertQueue(queue_name,{durable:false,autoDelete:true});
});
});
client.on('sendmsg', function(arg)
{
var payload_stringify = JSON.stringify(arg);
amqpconnection.createConfirmChannel().then(function(channelObjSuccess) {
channelObjSuccess.assertQueue(queue_name,{durable:false,autoDelete:true});
channelObjSuccess.sendToQueue(queue_name, new Buffer(payload_stringify), {},
function(err, ok)
{
if (err !== null)
console.log('Message Send Failure! ');
else
{
channelObjSuccess.close();
}
});
});
});
client.on('disconnect', function()
{
try {
console.log("AMPQ Connection Closed - Disconnect");
if(typeof(client.assignObj)!=undefined)
{
client.assignObj.close();
}
}
catch (alreadyClosed) {
console.log("RabbitMQ Connection Already Closed " + alreadyClosed.stackAtStateChange);
}
});
});
server.listen(port);

I think i found the answer, might be the issue is with the heartbeat as option while connecting to the AMQP.
Eg:
url = "amqp://turtle.rmq.cloudamqp.com/bqftjxzn?heartbeat=45";

Related

Close consumer connection to AMQP library in Nodejs

I use AMQP for my application. I want to close the connection to the consumer AMQP after all the message queues have been received. However, I don't know how to handle it. I will be very grateful and appreciated if someone help me. Thank you
var amqp = require('amqplib');
amqp.connect('amqp://localhost').then(function(conn) {
process.once('SIGINT', function() { conn.close(); });
return conn.createChannel().then(function(ch) {
var ok = ch.assertQueue('hello', {durable: false});
ok = ok.then(function(_qok) {
return ch.consume('hello', function(msg) {
console.log(" [x] Received '%s'", msg.content.toString());
}, {noAck: false});
});
return ok.then(function(_consumeOk) {
console.log(' [*] Waiting for messages. To exit press CTRL+C');
});
})
}).catch(console.warn);
conn.close() this close function will be close the connection

Emergency! Error: This socket has been ended by the other party

I revised appium source code, add my code, when i connect to the port that is forwarded to device and send command to port, it comes out:
Error: This socket has been ended by the other party
and my code is like this:
return await new Promise((resolve, reject) => {
try {
this.socketClient = net.connect(this.webSocket);
// Windows: the socket errors out when ADB restarts. Let's catch it to avoid crashing.
this.socketClient.on('error', (err) => {
if (!this.ignoreUnexpectedShutdown) {
//throw new Error(`Android bootstrap socket crashed: ${err}`);
log.debug('//////////////////////////////////')
log.debug(err)
log.debug('//////////////////////////////////')
throw new Error(`Android testbundle socket crashed: ${err}`)
}
});
this.socketClient.once('connect', () => {
log.info("Android bundle socket is now connected");
resolve();
});
} catch (err) {
reject(err);
}
})
after that, I use this.socketClient to send command like this:
async sendCommand(type, extra = {}) {
if (!this.socketClient) {
log.debug('==========socket closed========')
throw new Error('Socket connection closed unexpectedly');
}
return await new B((resolve, reject) => {
let cmd = Object.assign({cmd: type}, extra);
let cmdJson = `${JSON.stringify(cmd)}\n`;
log.debug(`Sending command to android testbundle: ${_.trunc(cmdJson, 1000).trim()}`);
this.socketClient.write(cmdJson);
this.socketClient.setEncoding('utf8');
let streamData = '';
this.socketClient.on('data', (data) => {
try {
streamData = JSON.parse(streamData + data);
// we successfully parsed JSON so we've got all the data,
// remove the socket listener and evaluate
this.socketClient.removeAllListeners('data');
if (streamData.status === 0) {
resolve(streamData.value);
}
log.debug("Received command result from bundle:" + JSON.stringify(streamData));
reject(errorFromCode(streamData.status));
} catch (ign) {
log.debug("Stream still not complete, waiting");
streamData += data;
}
})
})
}
But, I always get the error:
[debug] [bundle] //////////////////////////////////
[debug] [bundle] Error: This socket has been ended by the other party
at Socket.writeAfterFIN [as write] (net.js:291:12)
at ..\../lib/bundle.js:160:31
Anyone can help me...

node net socket connection timeout

I noticed, that my node server's net.createConnection() has a very long timeout before firing an error on some occasions (seems to be a particular problem with ports...)
i tried to connect to somedomain:9000 (listening, connecting and working as expected)
and to somedomain:1234 (same domain, different port, waiting around 2 minutes until "connect ETIMEDOUT")
When i connect to non-existent domains, i get an error right away, but not if i connect to unreachable ports on reachable hosts.
i need to determine if a machine is reachable in <1sec..
how do i handle this? Must be some way to notice an unreachable port in under 2minutes?
at least some kind of timeout that just sets the address as unreachable after a set amout of time?
Thanks
UPDATE: current Connection code:
this.openConnection = function() {
try {
console.log("[INFO] connecting to " + device.ip + ":" + device.port);
device.clientSocket = new net.createConnection(this.port,this.ip)
.on('connect', device.connected)
.on('data', device.inputReceived)
.on('error', function(err) {
if (err.code == "ENOTFOUND") {
console.log("[ERROR] No device found at this address!");
device.clientSocket.destroy();
return;
}
if (err.code == "ECONNREFUSED") {
console.log("[ERROR] Connection refused! Please check the IP.");
device.clientSocket.destroy();
return;
}
console.log("[CONNECTION] Unexpected error! " + err.message + " RESTARTING SERVER");
process.exit(1);
})
.on('disconnect', function() {
console.log("[CONNECTION] disconnected!");
});
} catch(err) {
console.log("[CONNECTION] connection failed! " + err);
}
};
When you connect, you can just set your own timer for whatever timeout you want and if the connect has not succeeded when that timer fires, then it did not succeed as quickly as you want.
This could be encapsulated in a single function with a single callback or returning a promise.
Based on your code, here's a shot at adding a timeout to it (untested code):
this.openConnection = function(timeout) {
var timer;
timeout = timeout || 2000;
try {
console.log("[INFO] connecting to " + device.ip + ":" + device.port);
device.clientSocket = new net.createConnection(this.port,this.ip)
.on('connect', function() {
clearTimeout(timer);
device.connected();
})
.on('data', function() {
clearTimeout(timer);
device.inputReceived();
})
.on('error', function(err) {
clearTimeout(timer);
if (err.code == "ENOTFOUND") {
console.log("[ERROR] No device found at this address!");
device.clientSocket.destroy();
return;
}
if (err.code == "ECONNREFUSED") {
console.log("[ERROR] Connection refused! Please check the IP.");
device.clientSocket.destroy();
return;
}
console.log("[CONNECTION] Unexpected error! " + err.message + " RESTARTING SERVER");
process.exit(1);
})
.on('disconnect', function() {
console.log("[CONNECTION] disconnected!");
});
timer = setTimeout(function() {
console.log("[ERROR] Attempt at connection exceeded timeout value");
device.clientSocket.end();
}, timeout);
} catch(err) {
console.log("[CONNECTION] connection failed! " + err);
}
};

node.js websocket crashes when client disconnect

I am very new to NodeJS and Websockets, but i am trying to play with it.
What i do is read incoming datas from Serial port, then send these datas to a web page using websocket.
From here everything works fine.
I use node-static to serve my web page
I use ws for websocket
The problem is when a client close his browser, then my NodeJS websocket server crashes with the following error :
root#WS-SERVER-2:~/app# node socketserver.js
open serial communication
Client disconnected.
/root/node-v0.10.29/lib/node_modules/ws/lib/WebSocket.js:187
else throw new Error('not opened');
^
Error: not opened
at WebSocket.send (/root/node-v0.10.29/lib/node_modules/ws/lib/WebSocket.js:187:16)
at sendAll (/root/app/socketserver.js:30:16)
at SerialPort.<anonymous> (/root/app/socketserver.js:58:8)
at SerialPort.emit (events.js:95:17)
at Object.module.exports.raw [as parser] (/root/node-v0.10.29/bin/node_modules/serialport/parsers.js:8:13)
at Object.SerialPort.options.dataCallback (/root/node-v0.10.29/bin/node_modules/serialport/serialport.js:143:15)
at SerialPortFactory.SerialPort._emitData (/root/node-v0.10.29/bin/node_modules/serialport/serialport.js:312:20)
at afterRead (/root/node-v0.10.29/bin/node_modules/serialport/serialport.js:290:18)
at /root/node-v0.10.29/bin/node_modules/serialport/serialport.js:304:9
at Object.wrapper [as oncomplete] (fs.js:459:17)
Here is my websocket/serialport code :
var WebSocketServer = require('../node-v0.10.29/lib/node_modules/ws').Server;
var SerialPort = require('../node-v0.10.29/bin/node_modules/serialport').SerialPort;
var serialPort;
var portName = '/dev/ttyACM0';
var sendData = "";
var wss = new WebSocketServer({port: 8080});
var CLIENTS=[];
wss.on('connection', function(ws) {
CLIENTS.push(ws);
ws.on('message', function(message) {
console.log('received: %s', message);
sendAll(message);
});
ws.on('close', function() {
console.log('Client disconnected.');
});
ws.on('error', function() {
console.log('ERROR');
});
ws.send("");
});
function sendAll(message)
{
for(var i=0;i<CLIENTS.length;i++)
{
CLIENTS[i].send(message);
}
}
serialListener();
function serialListener(debug)
{
var receivedData = "";
serialPort = new SerialPort(portName, {
baudrate: 9600,
dataBits: 8,
parity: 'none',
stopBits: 1,
flowControl: false
});
serialPort.on("open", function () {
console.log('open serial communication');
// Listens to incoming data
serialPort.on('data', function(data) {
receivedData += data.toString();
if (receivedData .indexOf('E') >= 0 && receivedData .indexOf('B') >= 0) {
sendData = receivedData .substring(receivedData .indexOf('B') + 1, receivedData .indexOf('E'));
receivedData = '';
}
// send the incoming data to browser with websockets.
sendAll(sendData);
});
});
}
Can someone help me to figure out what's wrong here ?
I think, you should remove the socket from your CLIENTS array on both close and error event. Otherwise it tries to send a message to a socket that is closed.
I was having this same issue. Turned out I was attempting to send events to sockets that were in the "closing" state. Checking that each socket was specifically open before broadcasting a message fixed it for me:
function sendAll(data){
for(var i = 0; i < clients.length; i++){
if(this.clients[i].readyState != this.clients[0].OPEN){
console.error('Client state is ' + this.clients[i].readyState);
}
else{
this.clients[i].send(data);
}
}
}
Try this while sending data to client:
- socket is my current web socket object.It overwrites the default >WebSocket.js class condition that throws "not-opened error".
if (socket.readyState != socket.OPEN) {
console.error('Client state is ' + socket.readyState);
//or any message you want
} else {
socket.send(JSON.stringify(object)); //send data to client
}

Mongoose opens 2 connections to DB on second request

I'm writing a small Node to just monitor MongoDB by making a simple query via Mongoose. If something is returned, the service is deemed as available. Here is my script
var res;
var logPrefix = '[MongoDB]';
var counter = 0;
var mongoose = require('mongoose');
// Simple schema and model for getting a companyprofiles document
var companyProfile = new mongoose.Schema({
_id: String
});
companyProfile.virtual('Id').get(function () {return this._id});
function closeConnection() {
console.log('8');
mongoose.connection.close(function () {
console.log('9');
console.log('%s Closed connection%d', logPrefix, counter);
});
}
function connectAndCheckHealth() {
console.log('2');
mongoose.connect('mongodb://localhost:27017/testdb');
console.log('3');
mongoose.connection.on('error', function(err) {
console.log('%s Error connecting to DB:\n%s %s', logPrefix, logPrefix, err);
res.send(503, 'ERR');
});
mongoose.connection.on('open', function() {
mongoose.connection.db.serverConfig.options.auto_reconnect = false;
});
console.log('4');
mongoose.connection.on('connected', checkHealth);
console.log('5');
mongoose.connection.on('close', function() {
console.log('%s Connection to MongoDB closed %d', logPrefix, counter);
});
}
function checkHealth() {
console.log('6');
cpModel = mongoose.model('companyProfile', companyProfile, 'companyprofiles');
cpModel.findById('spin', handleModelResponse);
}
function handleModelResponse(error, doc) {
console.log('7');
closeConnection();
console.log('10');
if (error !== null) {
console.log('11');
console.log('%s Error handling response from model:\n%s %s', logPrefix, logPrefix, error);
res.send(503, 'ERR');
} else {
console.log('12');
if (doc.Id.match(/company1/)) {
console.log('13');
console.log('%s App status is ok', logPrefix);
res.send(200, 'OK');
} else {
console.log('14');
console.log('%s Couldn\'t find the spin company profile. Found %s', logPrefix, doc.Id);
res.send(503, 'ERR');
}
}
}
module.exports = {
health: function(response) {
counter++;
var date = new Date();
console.log('%s Retrieving health from MongoDB at %s', logPrefix, date);
res = response;
console.log(mongoose.connection);
console.log('1');
connectAndCheckHealth();
console.log('15');
}
}
As you can see, I've peppered the script with console.log lines with numbers to try and work out the control flow. Here's the output:
1
2
3
4
5
15
6
6
6
7
8
[MongoDB] Connection to MongoDB closed 3
[MongoDB] Connection to MongoDB closed 3
[MongoDB] Connection to MongoDB closed 3
9
[MongoDB] Closed connection3
10
12
13
[MongoDB] App status is ok
7
8
9
[MongoDB] Closed connection3
10
12
13
[MongoDB] App status is ok
/home/GTP/healthcheck/node_modules/mongoose/lib/utils.js:413
throw err;
^
Error: Can't set headers after they are sent.
Notice that 6 appears three times (the callback after we have connected). I can't tell why we are opening multiple connections. I've turned autoconnect off and am closing the connection after every request.
Any help would be greatly appreciated.
Mongoose opens a pool of 5 connections by default; if you only want a single connection you can change your connect call to be:
mongoose.connect('mongodb://localhost:27017/testdb', { server: { poolSize: 1 }});
db.once('open') worked for me.
While testing my page, I had noticed that double and rapid form submits were triggering errors about the headers already sent. This stopped that.

Resources