could connect to kafka instance in node? - node.js

I have two computer running in the local network, one computer is installed with kafka instance on 192.168.1.3:9092. In another computer a short test program is running a kafka client to connect kafka instance and subscribe a topic.
my kafka-node is latest version, v4.1.3
const kafka = require('kafka-node');
const bp = require('body-parser');
//const config = require('./config');
try {
const Consumer = kafka.HighLevelConsumer;
const client = new kafka.KafkaClient("kafkaHost: '192.168.1.3:9092'");
let consumer = new kafka.Consumer(
client,
[{ topic: "dbserver1", partition: 0 }],
{
autoCommit: true,
fetchMaxWaitMs: 1000,
fetchMaxBytes: 1024 * 1024,
encoding: 'utf8',
fromOffset: false
}
);
consumer.on('message', async function(message) {
console.log('here');
console.log(
'kafka-> ',
message.value
);
})
consumer.on('error', function(err) {
console.log('error', err);
});
}
catch(e) {
console.log(e);
}
The code is shown above. However the code is always telling me
{ Error: connect ECONNREFUSED 127.0.0.1:9092
at Object._errnoException (util.js:992:11)
at _exceptionWithHostPort (util.js:1014:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1186:14)
code: 'ECONNREFUSED',
errno: 'ECONNREFUSED',
syscall: 'connect',
address: '127.0.0.1',
port: 9092 }
why it is showing 127.0.0.1 not 192.168.1.3?

Based on the comments, you're running the Debezium Kafka docker container... From the Debezium Docker tutorial...
If we wanted to connect to Kafka from outside of a Docker container, then we’d want Kafka to advertise its address via the Docker host, which we could do by adding -e ADVERTISED_HOST_NAME= followed by the IP address or resolvable hostname of the Docker host, which on Linux or Docker on Mac this is the IP address of the host computer (not localhost).
Sounds like your node code is not running in a container, or at least not on the same machine / Docker network
So you'll have to add -e ADVERTISED_HOST_NAME=192.168.1.3 to your docker run command

Related

Executing ksql query using node npm ksqlDb-client throwing an timeout error

Hi am trying to execute the KSQL query using npm package ksqlDb-client package, it throws an timeout error. I have attached the code as well, please let me know any issues over there.
when am hit this GET URL below method will execute https://localhost:5000/testKsql
exports.getKSQLStream = async () => {
const options = {
authorization: {
username: "admin",
password: "pw",
ssl: {
ca: CAs,
crt: myClientCert,
key: myClientKey,
}
},
host: 'https://ixxxx.xcxx.net',
timeout: 20000
}
const client = new KsqldbClient(options);
await client.connect();
const streamRes = await client.query('list streams;');
console.log("streams",streamRes);
await client.disconnect();
}
when I hit that URL from postman am getting below response in node console.
Error on Http2 client. Error: connect ETIMEDOUT 16.2XX.X4.xxx:8088
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1159:16) {
errno: -4039,
code: 'ETIMEDOUT',
syscall: 'connect',
address: '16.2XX.X4.xxx',
port: 8088
}
I faced recently with the same issue and found that library has bug with authorization. I pushed PR in repo, but you can patch your local copy in the same way.
https://github.com/Streaminy/ksqldb-client/pull/4

How to run Vault from my app instead of CLI?

I'm trying to start a Vault service in my NodeJS app.
Using CLI to use Vault is ok,
but i need it to work automatically when the app is started.
I try this
async started(ctx) {
var options = {
apiVersion: 'v1', // default
endpoint: 'http://127.0.0.1:8500', // default
};
// get new instance of the client
var vault = require("node-vault")(options);
// init vault server
vault.init({ secret_shares: 1, secret_threshold: 1 })
.then( (result) => {
var keys = result.keys;
// set token for all following requests
vault.token = result.root_token;
// unseal vault server
return vault.unseal({ secret_shares: 1, key: keys[0] })
})
.catch(console.error);
// see if it is ok
vault.status()
.then (res => {
console.log('STATuuuuuuuuuuusS', res);
})
.catch((err) => {
console.log("errrrrrreur status");
console.error(err.message);
});
But i've got this error:
RequestError: Error: connect ECONNREFUSED 127.0.0.1:8500
[...]
cause: Error: connect ECONNREFUSED 127.0.0.1:8500
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1141:16) {
errno: 'ECONNREFUSED',
code: 'ECONNREFUSED',
syscall: 'connect',
address: '127.0.0.1',
port: 8500
},
If i run this before, it worked
vault server -config=config.hcl
Even when i kill it, it seems to work without reloading it. I'm missing something here, for sure :)
I'm wondering if node-vault should start Vault server ? If not, i'm wondering how to start the Vault server from the app and not the CLI ?
If you know the good way to do it, or have clues, i'm all ears.
Nicolas
No, usually the code shouldn't start the server.
Yes, your code is working correctly. If you have not started the server, the error means that it is impossible to connect to the specified IP address and port, they are closed.
The vault server has nothing to do with it, the same behavior will be the database server or any other.

DNS Round Robin failover doesn't work with mqtt.js

I have a NodeJS Application that uses mqtt.js to connect to an emqx cluster.
The MQTT cluster contains of 2 nodes which I try to provide failover for using DNS Round Robin. So I have 1 A-Record (let's say mqtt.example.com) which points to 2 IPs (IP1 and IP2). When both nodes are online also my NodeJS application connects fine and subscribes to the selected topics.
Now on the MQTT nodes I can see what node the application is connected to. When I now stop the node that the application is connected to I expect that it would (sooner or later) fail over to the second active node.
I tested also with Loraserver (Which connected to MQTT) as well as the Node Red implementation of MQTT and both immediately connect to the active node when I stop the node they're connected to.
However my NodeJS application with mqtt.js keeps trying to connect to the node which I just stopped and doesn't try to connect to the active one.
Scenario explanation:
I have 2 Active nodes, IP1 and IP2
I connect Loraserver, Node Red and NodeJS to mqtt.example.com
All 3 applications connect to IP1
I stop IP1 node by shutting down the emqx process
Loraserver and Node Red will immediately connect to IP2 automatically
NodeJS with mqtt.js however keeps showing me error message
Error: connect ECONNREFUSED
with IP1 and doesn't fail over to IP2 (Kept it running for about 20 minutes and nothing happened. DNS lease time is set to 5 minutes if that's of any relavance)
How can I achiever failover using DNS Round Robing for an application using mqtt.js?
Thanks for any help
EDIT: As requested, added the testing code:
const mqtt = require('mqtt');
const tls = require('tls');
const MQTTTOPIC = 'test/upload';
const BROKER_URL = 'tls://mqtt.example.com';
const BROKER_PORT = '8883';
const MQTTUSER = 'username';
const MQTTPASS = 'password';
var mqttoptions = {
clientId: MQTTUSER,
port: BROKER_PORT,
keepalive: 60,
username: MQTTUSER,
password: MQTTPASS
};
var client = mqtt.connect(BROKER_URL, mqttoptions);
client.on('connect', mqtt_connect);
client.on('reconnect', mqtt_reconnect);
client.on('error', mqtt_error);
client.on('message', mqtt_messsageReceived);
client.on('close', mqtt_close);
function mqtt_connect() {
console.log("Connecting MQTT");
client.subscribe(MQTTTOPIC, mqtt_subscribe);
}
function mqtt_subscribe(err, granted) {
console.log("Subscribed to " + MQTTTOPIC);
if (err) { console.error(err); }
}
function mqtt_reconnect(err) {
console.log("Reconnect MQTT");
if (err) { console.error(err); }
client = mqtt.connect(BROKER_URL, mqttoptions);
}
function mqtt_error(err) {
console.error("MQTT Error!");
if (err) { console.error(err); }
}
function after_publish() {
//do nothing
}
function mqtt_close() {
console.warn("Close MQTT");
}
function mqtt_messsageReceived(topic, message, packet) {
console.log("Message: " + message + " --- Received on Topic " + topic);
}
EDIT 2:
In case it matters, I'm running the code with pm2
EDIT 3:
Plus the complete log output:
17|LOCALTE | Connecting MQTT
17|LOCALTE | Subscribed to test/upload
17|LOCALTE | Close MQTT
17|LOCALTE | Reconnect MQTT
17|LOCALTE | Error: connect ECONNREFUSED IP1:8883
17|LOCALTE | at Object.exports._errnoException (util.js:1034:11)
17|LOCALTE | at exports._exceptionWithHostPort (util.js:1057:20)
17|LOCALTE | at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1096:14)
17|LOCALTE | MQTT Error!
17|LOCALTE | { Error: connect ECONNREFUSED IP1:8883
17|LOCALTE | at Object.exports._errnoException (util.js:1034:11)
17|LOCALTE | at exports._exceptionWithHostPort (util.js:1057:20)
17|LOCALTE | at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1096:14)
17|LOCALTE | code: 'ECONNREFUSED',
17|LOCALTE | errno: 'ECONNREFUSED',
17|LOCALTE | syscall: 'connect',
17|LOCALTE | address: 'IP1',
17|LOCALTE | port: 8883 }
17|LOCALTE | Close MQTT
17|LOCALTE | Reconnect MQTT
[...]
Firstly you should not be calling connect() in the on.('reconnect') callback. The library will handle all of this for you.
...
function mqtt_reconnect(err) {
console.log("Reconnect MQTT");
if (err) { console.error(err); }
}
...
If it still doesn't work once you've removed this, as a work around you can list a group of servers that the library will round robin on it's own.
var mqttoptions = {
clientId: MQTTUSER,
port: BROKER_PORT,
keepalive: 60,
username: MQTTUSER,
password: MQTTPASS
servers:[
{
protocol: 'mqtts',
host: 'ip-address-1',
port: 8883
},
{
protocol: 'mqtts',
host: 'ip-address-2',
port: 8883
}
]
}

Error EADDRNOTAVAIL on socket.send() in node (SSDP protocol)

I'm trying to implement a UPnP discovery service tool (SSDP protocol), I did something similar in python following this post: https://www.electricmonk.nl/log/2016/07/05/exploring-upnp-with-python/ and I would like to port it to node (v. 8.6.0) and typescript however I'm getting the following error when I try to send the message (socket.send(...)):
{ Error: send EADDRNOTAVAIL 239.255.255.250:1900
at Object._errnoException (util.js:1019:11)
at _exceptionWithHostPort (util.js:1041:20)
at SendWrap.afterSend [as oncomplete] (dgram.js:475:11)
code: 'EADDRNOTAVAIL',
errno: 'EADDRNOTAVAIL',
syscall: 'send',
address: '239.255.255.250',
port: 1900 }
I've found a snippet of code for node, that makes this exact thing (https://coolaj86.com/articles/adventures-in-upnp-with-node-js/) and I think that my code is quite equivalent however I cannot see why my code isn't working
const dgram = require('dgram');
const socket = dgram.createSocket('udp4');
let msg_txt = 'M-SEARCH * HTTP/1.1\r\n' +
'HOST:239.255.255.250:1900\r\n' +
'ST:upnp:rootdevice\r\n' +
'MX:2\r\n' +
'MAN:"ssdp:discover"\r\n\r\n';
const message = Buffer.from(msg_txt);
socket.on('message', (msg: Buffer, info: any) => {
console.log(msg.toString());
});
socket.bind({
address: '239.255.255.250',
port: 1900
}, (err) => {
!!err && console.error(err);
});
socket.on('listening', () => {
console.log('Sending msg...');
socket.send(message, 0, message.length, 1900, '239.255.255.250', (err) => {
!!err && console.error(err); // err != null
});
});
I suspect that is a typical one-line-problem but after a while I couldn't find it out, any help is welcome.
I saw it, in node the API is a bit different, the binding should be against the '0.0.0.0' iface and the port 0 (for a random number), so changing the binding command to the following code just fix it:
socket.bind({
address: '0.0.0.0',
port: 0
}, (err) => {
!!err && console.error(err);
});
In python I called to socket.recvfrom() method to get the UPnP devices responses, there is not an explicit socket binding.
For what it's worth, I had a similar setup using Node 10 on Windows and creating a udp4 socket on localhost. Weirdly enough, the setup described in the accepted answer worked on every OS and Node version except Node 10 on Windows in my CI tests. In order to get things to work, I had to explicitly bind to the address localhost instead of 0.0.0.0, like so:
const socket = dgram.createSocket('udp4').unref();
socket.bind({
address: 'localhost',
port: 0
}, (err) => {
!!err && console.error(err);
});

Port 9200 Refused Connection?

I'm trying to implement an elasticsearch client in NodeJS on a Cloud9 workspace and I'm just trying to get it running. My app runs on port 5678 and my MongoDB runs on 27017. I have tried searching for other answers, but I haven't really found anything particularly useful. This is the error message that I receive when trying to connect to localhost:9200.
Elasticsearch ERROR: 2015-06-26T04:24:19Z
Error: Request error, retrying -- connect ECONNREFUSED
at Log.error (/home/ubuntu/workspace/node_modules/elasticsearch/src/lib/log.js:213:60)
at checkRespForFailure (/home/ubuntu/workspace/node_modules/elasticsearch/src/lib/transport.js:192:18)
at HttpConnector.<anonymous> (/home/ubuntu/workspace/node_modules/elasticsearch/src/lib/connectors/http.js:153:7)
at ClientRequest.wrapper (/home/ubuntu/workspace/node_modules/elasticsearch/node_modules/lodash/index.js:3128:19)
at ClientRequest.emit (events.js:95:17)
at Socket.socketErrorListener (http.js:1552:9)
at Socket.emit (events.js:95:17)
at net.js:441:14
at process._tickCallback (node.js:442:13)
Elasticsearch TRACE: 2015-06-26T04:24:19Z
-> HEAD http://localhost:9200/
<- 0
Elasticsearch WARNING: 2015-06-26T04:24:19Z
Unable to revive connection: http://localhost:9200/
Elasticsearch WARNING: 2015-06-26T04:24:19Z
No living connections
Trace: elasticsearch cluster is down!
at Server (/home/ubuntu/workspace/app.js:32:13)
at respond (/home/ubuntu/workspace/node_modules/elasticsearch/src/lib/transport.js:251:9)
at sendReqWithConnection (/home/ubuntu/workspace/node_modules/elasticsearch/src/lib/transport.js:171:7)
at next (/home/ubuntu/workspace/node_modules/elasticsearch/src/lib/connection_pool.js:213:7)
at process._tickCallback (node.js:442:13)
.
My code for the elastic search client is very simple
var client = new elasticsearch.Client({
hosts: 'localhost:9200',
log: 'trace'
});
client.ping({
// ping usually has a 3000ms timeout
requestTimeout: 30000,
// undocumented params are appended to the query string
hello: "elasticsearch!"
}, function (error) {
if (error) {
console.trace('elasticsearch cluster is down!');
} else {
console.log('All is well');
}
});
If I try to connect to localhost:5678, I don't get an error refused, but the elastic cluster is still down? Any suggestions would be helpful, thanks :)
//Client.js
const es = require('elasticsearch');
const esClient = new es.Client({
host: {
protocol: 'http',
host: 'localhost',
port: 9200
},
log: 'trace'
});
module.exports = esClient;
//ping.js
const esClient = require('./client');
esClient.ping({
// ping usually has a 3000ms timeout
requestTimeout: 3000
}, function (error) {
if (error) {
console.trace('elasticsearch cluster is down!');
} else {
console.log('All is well');
}
});
Hey to anyone who wants to know what I did. I basically just downloaded elasticsearch onto cloud9 and ran it. Then I pinged the port accordingly and it worked. Looks like a noobie mistake on my part :P
In my case, stock elasticsearch with everything in default and using the JS client results in this error.
(short term) fix: http.cors.enabled and https.cors.allow-origin settings

Resources