Socket closed abruptly during opening handshake while trying to connect to RabbitMq - node.js

I have a simple NodeJs application that should connect to RabbitMq.
The code:
const amqp = require('amqplib/callback_api');
const amqpUri = "amqp://user:password#localhost:5672"
if (amqpUri == null)
throw Error('Missing AMQP_URI environment variable.');
amqp.connect(amqpUri, function(error0, connection) {
if (error0)
throw error0;
connection.createChannel(function(error1, channel) {
if (error1) {
throw error1;
}
const exchangeName = 'product.event';
const queueName1 = 'create';
const routingKey1 = 'create';
const queueName2 = 'delete';
const routingKey2 = 'delete';
channel.assertExchange(exchangeName, 'topic', {
durable: false,
});
// create
channel.assertQueue(queueName1, {
durable: false,
});
channel.bindQueue(queueName1, exchangeName, routingKey1);
channel.consume(queueName1, (msg) => consumeCreated(channel, msg));
// delete
channel.assertQueue(queueName2, {
durable: false,
});
channel.bindQueue(queueName2, exchangeName, routingKey2);
channel.consume(queueName2, (msg) => consumeDeleted(channel, msg));
});
});
Then run a RabbitMq image with:
docker run -d --hostname my-rabbit --name some-rabbit -p 5672:15672 -e RABBITMQ_DEFAULT_USER=user -e RABBITMQ_DEFAULT_PASS=password rabbitmq:3-management
I can access the rabbitmq and connect with the credentials user/password at http://localhost:5672.
For some reason, I have the error:
/home/hamuto/CLO902-Group35/indexer/app.js:12
throw error0;
^
Error: Socket closed abruptly during opening handshake
at Socket.endWhileOpening (/home/hamuto/CLO902-Group35/indexer/node_modules/amqplib/lib/connection.js:260:17)
at Socket.emit (events.js:326:22)
at endReadableNT (_stream_readable.js:1241:12)
at processTicksAndRejections (internal/process/task_queues.js:84:21)

i see this is not likely the case as your using the correct port, however I was getting the exact same error messages when I tried using HTTP port instead of tpc port.
Again I know this isnt your issue but if guess it could help you pinpoint potential failpoints.

Related

Failed to connect with RabbitMQ server when sending large amount of messages

I am using Cloudamqp to connect with RabbitMq when I am trying to send 10 messages its publishing data successfully to the queue but when I am trying to send 2,000 messages its showing connection failed error shown below:
Error Error: connect ECONNREFUSED 15.206.75.114:5671
at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1247:16) {
errno: -111,
code: 'ECONNREFUSED',
syscall: 'connect',
address: '15.206.75.114',
port: 5671
}
Error Error: Expected ConnectionOpenOk; got <ConnectionClose channel:0>
at /home/digvijay/test/test-lorien/node_modules/amqplib/lib/connection.js:167:14
at /home/digvijay/test/test-lorien/node_modules/amqplib/lib/connection.js:159:12
at TLSSocket.recv (/home/digvijay/test/test-
lorien/node_modules/amqplib/lib/connection.js:507:12)
I am reading the Excel file using XLSX library and sending those rows to the queue. Below is my code:
const express = require('express');
const XLSX = require("xlsx");
const amqp = require('amqplib/callback_api');
const app = express();
const port = process.env.PORT || 3300;
// Reading our test file
const file = XLSX.readFile('./limit9.xlsx')
app.get('/', (req, res) => {
const sheets = file.SheetNames;
for (let i = 0; i < sheets.length; i++) {
const temp = XLSX.utils.sheet_to_json(
file.Sheets[file.SheetNames[i]])
temp.forEach((res) => {
sendData(res); //Here sending data to the queue
});
}
});
function sendData(res) {
amqp.connect(`amqps://nuogafvveJoldl_RhEyfs7qJzX0BIRep6J8rFIN-0#puffin.rmq2.cloudamqp.com/xxxxxxx`, (err, connection) => {
if (err) {
console.log("Error",err);
}
else {
connection.createChannel((err, channel) => {
if (err) {
throw err;
}
else {
let queu = "review_data";
channel.assertQueue(queu, {
durable: false
});
var json = JSON.stringify(res);
channel.sendToQueue(queu, Buffer.from(json));
}
});
}
});
}
Why is it throwing connection error when I am sending large amount of messages but works fine for sending few messages?

Node.js redis#4 Upgrade: SocketClosedUnexpectedlyError: Socket closed unexpectedly

I've got some legacy code that I'm upgrading from version 3 of the Node.js redis library to version 4 of the Node.js redis library. The basic shape of the code looks like this
var redis = require('redis')
var client = redis.createClient({
port: '6379',
host: process.env.REDIS_HOST,
legacyMode: true
})
client.connect()
client.flushall(function (err, reply) {
client.hkeys('hash key', function (err, replies) {
console.log("key set done")
client.quit()
})
})
console.log("main done")
When I run this code with redis#4.3.1, I get the following error, and node.js exits with a non-zero status code
main done
key set done
events.js:292
throw er; // Unhandled 'error' event
^
SocketClosedUnexpectedlyError: Socket closed unexpectedly
at Socket.<anonymous> (/Users/astorm/Documents/redis4/node_modules/#redis/client/dist/lib/client/socket.js:182:118)
at Object.onceWrapper (events.js:422:26)
at Socket.emit (events.js:315:20)
at TCP.<anonymous> (net.js:673:12)
Emitted 'error' event on Commander instance at:
at RedisSocket.<anonymous> (/Users/astorm/Documents/redis4/node_modules/#redis/client/dist/lib/client/index.js:350:14)
at RedisSocket.emit (events.js:315:20)
at RedisSocket._RedisSocket_onSocketError (/Users/astorm/Documents/redis4/node_modules/#redis/client/dist/lib/client/socket.js:205:10)
at Socket.<anonymous> (/Users/astorm/Documents/redis4/node_modules/#redis/client/dist/lib/client/socket.js:182:107)
at Object.onceWrapper (events.js:422:26)
at Socket.emit (events.js:315:20)
at TCP.<anonymous> (net.js:673:12)
While in redis#3.1.2 it runs (minus the client.connect()) without issue.
I've been able to work around this by replacing client.quit() with client.disconnect(), but the actual code is a little more complex than the above example and I'd rather use the graceful shutdown of client.quit than the harsher "SHUT IT DOWN NOW" of client.disconnect().
Does anyone know what the issue here might be? Why is redis#4 failing with a SocketClosedUnexpectedlyError: Socket closed unexpectedly error.
What I found so far is that after a while (keepAlive default is 5 minutes) without any requests the Redis client closes and throws an error event, but if you don't handle this event it will crash your application.
My solution for that was:
/* eslint-disable no-inline-comments */
import type { RedisClientType } from 'redis'
import { createClient } from 'redis'
import { config } from '#app/config'
import { logger } from '#app/utils/logger'
let redisClient: RedisClientType
let isReady: boolean
const cacheOptions = {
url: config.redis.tlsFlag ? config.redis.urlTls : config.redis.url,
}
if (config.redis.tlsFlag) {
Object.assign(cacheOptions, {
socket: {
// keepAlive: 300, // 5 minutes DEFAULT
tls: false,
},
})
}
async function getCache(): Promise<RedisClientType> {
if (!isReady) {
redisClient = createClient({
...cacheOptions,
})
redisClient.on('error', err => logger.error(`Redis Error: ${err}`))
redisClient.on('connect', () => logger.info('Redis connected'))
redisClient.on('reconnecting', () => logger.info('Redis reconnecting'))
redisClient.on('ready', () => {
isReady = true
logger.info('Redis ready!')
})
await redisClient.connect()
}
return redisClient
}
getCache().then(connection => {
redisClient = connection
}).catch(err => {
// eslint-disable-next-line #typescript-eslint/no-unsafe-assignment
logger.error({ err }, 'Failed to connect to Redis')
})
export {
getCache,
}
anyway... in your situation try to handle the error event
client.on('error', err => logger.error(`Redis Error: ${err}`))

Error: read ECONNRESET while connection rabbitmq with nodejs

I've encountered following error message while connection our external RabbitMQ with NodeJS as follow:
Error: read ECONNRESET
at TCP.onStreamRead (internal/stream_base_commons.js:205:27) {
errno: 'ECONNRESET',
code: 'ECONNRESET',
syscall: 'read'
}
and my nodejs code is as follow:
const amqp_url = "amqp://un:pw#sb-mq.com:9901/my-vhost";
amqp.connect(amqp_url, function (error0, connection) {
if (error0) {
throw error0;
}
connection.createChannel(function (error1, channel) {
if (error1) {
throw error1;
}
var queue = 'hello';
var msg = 'Hello World!';
channel.assertQueue(queue, {
durable: false
});
channel.sendToQueue(queue, Buffer.from(msg));
console.log(" [x] Sent %s", msg);
});
setTimeout(function () {
connection.close();
process.exit(0);
}, 500);
});
But the thing is when I've setup RabbidMQ locally with same configuration but using default port (like amqp://un:pw#localhost:5672/my-vhost), it was working perfectly. Please let me know how to troubleshoot that one, thanks.
"ECONNRESET" means the other side of the TCP conversation abruptly closed its end of the connection.
see How do I debug error ECONNRESET in Node.js?
about RabbitMQ check if rabbitmq actually is active in that port, just:
telnet sb-mq.com 9901
from your client machine and check the firewall configuration.
You may have another service running on 9901
ECONNRESET is network problem, rabbitmq can work in different ports without problems
I found that issue has been resolved when I've tried to use amqps instead of amqp.

How can I connect to my EC2 Instance via SSH with an AWS Lambda Function?

I'm attempting to ssh into an ec2 instance with a lambda function. I keep receiving a null value for my response every time I try run my function with my logs displaying the following error:
START RequestId: xxxx-xxxx-xxxx-xxxx-xxxx Version: $LATEST
2020-02-19T22:56:16.574Z xxxx-xxxx-xxxx-xxxx-xxxx INFO failed connection, boo
2020-02-19T22:56:16.576Z xxxx-xxxx-xxxx-xxxx-xxxx INFO Error: Timed out while waiting for handshake
at Timeout._onTimeout (/var/task/node_modules/ssh2/lib/client.js:687:19)
at listOnTimeout (internal/timers.js:531:17)
at processTimers (internal/timers.js:475:7) {
level: 'client-timeout'
}
With it being a timed out error, I figured it was an issue with connecting to the instance rather than my code, but the lambda is apart of the same VPC that the EC2 is apart of, along with a security group enabling ssh connections. I'm also able to connect to ssh into the instance manually as well.
exports.handler = async (event) => {
const fs = require('fs')
const SSH = require('simple-ssh');
const pemfile = 'xxx.pem';
const user = 'ec2-user';
const host = 'xx.xx.xx.xx';
// all this config could be passed in via the event
const ssh = new SSH({
host: host,
user: user,
key: fs.readFileSync(pemfile)
});
let cmd = "ls";
if (event.cmd == "long") {
cmd += " -l";
}
let prom = new Promise(function(resolve, reject) {
let ourout = "";
ssh.exec('mkdir /home/ec2-user/ssh_success', {
exit: function() {
ourout += "\nsuccessfully exited!";
resolve(ourout);
},
out: function(stdout) {
ourout += stdout;
}
}).start({
success: function() {
console.log("successful connection!");
},
fail: function(e) {
console.log("failed connection, boo");
console.log(e);
}
});
});
const res = await prom;
const response = {
statusCode: 200,
body: res,
};
return response;
};

Error: Can't add new command when connection is in closed state

I have recently deployed my node.js API application on live server. I am getting these issue on live server.
I have googled it, but could not get any exact solution. Can anyone suggest how can i solve this problem?
{ Error: read ETIMEDOUT at TCP.onread (net.js:622:25) errno: 'ETIMEDOUT', code: 'ETIMEDOUT', syscall: 'read', fatal: true }
{ Error: Can't add new command when connection is in closed state at PoolConnection._addCommandClosedState }
I amd using the mysql connection pool like this
var mysql = require('mysql2');
var mysqlPool = mysql.createPool({
host: 'localhost',
user: 'root',
password: 'xyz',
database: 'xyz',
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
});
module.exports = mysqlPool;
I had a similar problem and ended up having to put the connection request in it's own .js file and import it into the controller-
connectionRequest.js
module.exports = function () {
let mysql = require('mysql2')
let connCreds = require('./connectionsConfig.json');
//Establish Connection to the DB
let connection = mysql.createConnection({
host: connCreds["host"],
user: connCreds['username'],
password: connCreds['password'],
database: connCreds['database'],
port: 3306
});
//Instantiate the connection
connection.connect(function (err) {
if (err) {
console.log(`connectionRequest Failed ${err.stack}`)
} else {
console.log(`DB connectionRequest Successful ${connection.threadId}`)
}
});
//return connection object
return connection
}
Once I did that I was able to import it into my query on the controller file like so
ControllerFile.js
let connectionRequest = require('../config/connectionRequest')
controllerMethod: (req, res, next) => {
//Establish the connection on this request
connection = connectionRequest()
//Run the query
connection.query("SELECT * FROM table", function (err, result, fields) {
if (err) {
// If an error occurred, send a generic server failure
console.log(`not successful! ${err}`)
connection.destroy();
} else {
//If successful, inform as such
console.log(`Query was successful, ${result}`)
//send json file to end user if using an API
res.json(result)
//destroy the connection thread
connection.destroy();
}
});
},
After a lot of messing around I was able to solve the problem by destroying the connection, waiting (this is the important page) and getting the connection again.
conn = await connPool.getConnection();
// We have error: Can't add new command when connection is in closed state
// I'm attempting to solve it by grabbing a new connection
if (!conn || !conn.connection || conn.connection._closing) {
winston.info('Connection is in a closed state, getting a new connection');
await conn.destroy(); // Toast that guy right now
sleep.sleep(1); // Wait for the connection to be destroyed and try to get a new one, you must wait! otherwise u get the same connection
conn = await connPool.connection.getConnection(); // get a new one
}

Resources