Message not receiving after publishing. RABBITMQ MQTT - node.js

Am learning MQTT and facing some issues understanding MQTT with RabbitMQ from http://blog.airasoul.io/the-internet-of-things-with-rabbitmq-node-js-mqtt-and-amqp/.
So, the issue here is when I run publisher code, a queue is added mqtt-subscription-test-qos1 but when I message doesn't get added in that queue. Although I've added binding of amq.topic to this queue with key-binding 'presence'.
This is my publisher code
var payload = {
message : 'Hello'
};
var client = mqtt.connect(url, { clientId: 'test-', clean:true});
client.on('connect', function () {
client.publish('presence', JSON.stringify(payload), { qos: 1 }, function() {
console.log("Sent");
client.end();
process.exit();
});
});
and below is my subscriber code.
var client = mqtt.connect(url, { clientId: 'test-', clean:true});
client.on('connect', function () {
client.subscribe('presence', { qos: 1 });
});
client.on('message', function (topic, message) {
console.log('received message ', message.toString());
});
This works, when I don't declare any options with connect function in publisher code. So what I don't get is, isn't publisher supposed to create a queue and then publish to topics?
What am I doing wrong?

You don't need to create a queue before publishing to the topic. When you publish first MQTT message, a queue gets created automatically with the default exchange name "amq.topic" and binding key same as your topic name.
I suspect your subscriber is not receiving the messages published since it starts and subscribes to the topic AFTER the publisher publishes the messages. Try by starting your subscriber first and then start your publisher.

Related

How can I deal with message processing failures in Node.js using MQTT?

I'm using a service written in Node.js to receive messages via MQTT (https://www.npmjs.com/package/mqtt) which then writes to a database (SQL Server using mssql).
This will work very nicely when everything is functioning normally, I create the mqtt listener and subscribe to new message events.
However, if the connection to the DB fails (this may happen periodically due to a network outage etc.), writing the message to the database will fail and the message will be dropped on the floor.
I would like to tell the MQTT broker - "I couldn't process the message, keep it in the buffer until I can."
var mqtt = require('mqtt')
var client = mqtt.connect('mymqttbroker')
client.on('connect', function () {
client.subscribe('messagequeue')
})
client.on('message', function (topic, message) {
writeMessageToDB(message).then((result) => {console.log('success'};).catch((err) => {/* What can I do here ?*/});
})
Maybe set a timeout on a resend function? Probably should be improved to only try n times before dropping the message, but it's definitely a way to do it. This isn't tested, obviously, but it should hopefully give you some ideas...
var resend = function(message){
writeMessageToDB(message).then((result) => {
console.log('Resend success!')
})
.catch((err) => {
setTimeout(function(message){
resend(message);
}, 60000);
});
}
client.on('message', function (topic, message) {
writeMessageToDB(message).then((result) => {
console.log('success')
})
.catch((err) => {
resend(message);
});
});

Message getting published endlessly with MQTT and Node.js

I have a mosquitto broker running on one of my machines (say: mqtt://10.0.0.50:1883).
I am trying to use MQTT with Node in an IoT gateway to receive messages from a mobile app and based on the topic for which message was sent perform some function. Once the action is complete publish another message on the same topic from gateway for mobile apps.
Gateway side:
client.on('connect', function () {
if (client.connected) {
client.subscribe(topics, {qos: 1}, function (err, granted) {
console.log('Subscribed to topics: ' + JSON.stringify(granted));
});
}
});
client.on('message', function (topic, message) {
switch (topic.toUpperCase()) {
case 'TEST':
console.log('test topic Called');
client.publish(topic, "test topic response msg", {qos: 1},
function () {
console.log("message response sent");
});
}
});
I tried this piece of code with another sample node.js code.
Client side:
client.on('connect', function () {
if (client.connected) {
client.subscribe("test", {qos: 1}, function (err, granted) {
console.log('Subscribed to topics: ' + JSON.stringify(granted));
});
client.publish("test", "send_me_test", {qos: 1}, function () {
console.log("request message published");
});
}
});
client.on('message', function (topic, message) {
console.log("Topic: " + topic + " request: " + message);
});
Response that I get after running client.js:
Connected to the broker at: mqtt://10.0.0.50:1883
Subscribed to topics: [{"topic":"test","qos":1}]
message published
Topic: test request: send_me_test
Topic: test request: test topics response msg
Topic: test request: test topics response msg
Topic: test request: test topics response msg
which goes on endlessly.
On the gateway side:
Jun 21 08:53:56 intel-quark api-server[16975]: test topic Called
Jun 21 08:53:56 intel-quark api-server[16975]: publishing response for topic: test with data: "test topics response msg"
Jun 21 08:53:56 intel-quark api-server[16975]: message published
keeps on repeating endlessly.
I am not able to figure out why it's happening likewise. My desired output was one response publish for one request publish.
Your gateway is subscribing to the same topic as it is publishing on to so since it will receive it's own messages these will just loop for ever.
Responding on the same topic that a message is received on is not normally a good idea unless the message body has something in it to mark it as a response that can be checked to prevent loops like this.

Mosca sends multiple messages continously

I have setup a node js server with Mosca running on it. Clients are able to connect to the Mosca server and publish a message. I need to the send an acknowledgment in the form of a message(subscribed to some topic) back to the client.
The below code sends multiple messages continuously once the message is published by the client. Am I missing anything?
var settings = {
port: 1882,
backend: ascoltatore
};
var message = {
topic: 'crofters',
payload: 'OK', // or a Buffer
qos: 2
};
var server = new mosca.Server(settings);
server.on('clientConnected', function(client) {
console.log('client connected', client.id);
});
// fired when a message is received
server.on('published', function(packet, client ) {
var packet_payload = packet.payload;
packet_payload = packet_payload.toString();
console.log('Published', packet_payload);
server.publish(message, function() {
console.log('done!');
});
});
server.on('ready', setup);
function setup() {
console.log('Mosca server is up and running');
}
The event listener server.on('published', function(packet, client){...} listens to every publishing events, including the server's.
What is happening is that when you use server.publish(message, function(){...}) inside that listener it triggers another published event, which is immediately caught by the listener.
It never stops publishing because it never stops catching its own events.
I have been facing similar issues. If you notice, Mosca has only QoS 0 and Qos 1
So I suppose the broker tries to send the same message more than once "at least once" until it receives some acknowledgement from a client. Check this document out

how to write sender and receiver for common-mq in nodejs?

I am very new to nodejs. I need to send a message to rabbitMQ using common-mq module. I have installed this package by using the below command
npm install common-mq
I am not able to write the sender and receiver using this. Can anyone please help me in writing the sender and receiver using nodejs?
var commonmq = require('common-mq');
var connect = commonmq.connect('amqp://localhost:5672/queue');
How do I proceed after this?
sender.js looks like below
var commonmq = require("common-mq");
var queue = commonmq.connect('amqp://localhost:5672/queue', { implOptions: { defaultExchangeName: '' }});
var msg =JSON.stringify("Hello world");
console.log("going for ready");
queue.on('ready',function () {
console.log("inside event");
setTimeout(function() { queue.publish({ task: 'take out trash' }); }, 1000);
});
//queue.publish({ task: 'sweep floor' });
queue.on('error',function(err){
console.log("error is:"+err);
});
The receiver code goes like this
var commonmq = require("common-mq");
var queue = commonmq.connect('amqp://localhost:5672/queue', { implOptions: { defaultExchangeName: '' }
});
queue.on('message', function(message) {
console.log('Got a new message', message);
});
queue.on('error',function(e){
console.log("errrorrr ",e);
});
No messages are received. Please suggest me where am I messing up the things?
After you setup the service, you can listen for new messages or send new ones.
Receiver:
The receiver listens on a queue and performs actions based on the messages:
//setup the service
var queue = commonmq.connect('amqp://localhost:5672/queue');
queue.on('message', function(message) {
console.log('Got a new message', message);
//do something
});
//listen eventually on other events (error, ready)
Sender:
The sender publishes new messages. Even a receiver could do it...
//setup the service
var queue = commonmq.connect('amqp://localhost:5672/queue');
queue.publish(yourMessageAsObject);
There are a few other events you could listen to (for example in case of errors). Just check the manual on the npm site.

Publisher and subscriber not working in negative scenarios

Hi I am using zeroMQ for my node application where i use the publisher and subscriber for message queuing.Below is my code
Publisher.js
var zmq = require('zmq')
var publisher = zmq.socket('pub')
publisher.bind('tcp://127.0.0.1:7000', function(err) {
if(err)
console.log(err)
else
console.log("Listening on 7000...")
})
setTimeout(function() {
console.log('sent');
publisher.send("hi")
}, 1000)
process.on('SIGINT', function() {
publisher.close()
console.log('\nClosed')
})
Subscriber.js
var zmq = require('zmq')
var subscriber = zmq.socket('sub')
subscriber.on("message", function(reply) {
console.log('Received message: ', reply.toString());
})
subscriber.connect("tcp://localhost:7000")
subscriber.subscribe("")
process.on('SIGINT', function() {
subscriber.close()
console.log('\nClosed')
})
The above code is working fine if both the publisher and subscriber are running.If i stop my subscriber i'm not able to receive the publisher's data when the subscriber is offline.I want to persist the data even if my subscriber is down.I'm stuck here.Any help will be much appreciated.
See the 'Last value caching' pattern on zmq docs site. You can extend the example with the client first subscribing to a pattern with the latest item it had received, and the lvc proxy to resend the missing values(it has to cache them first). But this might work for a small number of cached items where disconnects happen rarely, otherwise PUSH might be the better option. PUB-SUB is not intended to support buffering.

Resources