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.
Related
We are using azure-iot-device-mqtt node package to connect a debian computer to the Azure IOT Hub. We have noticed that when the Internet drops (i.e. we disconnect it) Device Explorer thinks the device is still connected (for about 10 seconds) and messages being fired in this period do not reach the device (or get queued). After 10 seconds they appear in the Device Explorer queue. Also the device still thinks it's connected and does not recover the connection.
We have tried package versions 1.1.17 and 1.2.1 and have the same symptoms on both.
var clientFromConnectionString = require('azure-iot-device-mqtt').clientFromConnectionString;
var Message = require('azure-iot-device').Message;
var connectionString = 'xxx';
var client = clientFromConnectionString(connectionString);
var connectCallback = function (err) {
if (err) {
console.error('Could not connect: ' + err);
} else {
console.log('Client connected');
var message = new Message('some data from my device');
client.sendEvent(message, function (err) {
if (err) console.log(err.toString());
});
client.on('message', function (msg) {
console.log(msg);
client.complete(msg, function () {
console.log('completed');
});
});
client.on('disconnect', function () {
console.log("disconnect");
});
}
};
client.open(connectCallback);
N.b We require MQTT as we are using direct-method functionality.
With the AMQP package as soon as any disconnection the messages from the cloud instantly go into the queue.
Summary of issues:
MQTT messages lost for first 10-15 seconds of disconnection (After this they are queued cloud side).
MQTT+AMQP clients does not detect disconnects.
Any advice would be greatly appreciated.
Thanks,
David
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);
});
});
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.
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.
Hi im writting a publisher and subscriber in nodejs using the zeromq 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",function(err) {
if (err) {
console.log( 'Error binding socket' );
return;
}
subscriber.close(); // This is fine! The socket is ready!
})
subscriber.subscribe("")
process.on('SIGINT', function() {
subscriber.close()
console.log('\nClosed')
})
When the publisher is down or the subscriber is down im trying to capture the error by writting a call back.But in both the cases the srror doesnt seem to be captured.I am stuck here dont know where am going wrong.Any help will be much appreciated.
ZeroMq does not raise errors when peers disconnect. The physical aspects of connect and disconnect are handled transparently and hidden from the application.
One way to force ZeroMq to raise an error if the peer is unavailable is with ROUTER and router mandatory option set to true. If ROUTER attempts to send to a peer that doesn't physically exist, ROUTER will raise an exception.