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.
Related
I am setting up a web socket server with socket.io and it seems like that messages are sent at least twice. Sometimes even trice. (very rarely even 4+ times) They are never sent once though. How should I setup my handlers or my client code so every message is received exactly once all the time?
My client is in swift and my server in node.js. I am running Ubuntu 16.04 on the server itself.
Node.js:
// Here is an array of all connections to the server
var connections = {};
io.sockets.on('connection', newConnection);
function newConnection(socket) {
socket.on('add-user', function(user) {
connections[user.id] = {
"socket": socket.id
};
});
socket.on('chat-message', function(message) {
console.log(message);
if (connections[message.receiver]) {
console.log("Send to: " + connections[message.receiver].socket);
// Here are some varients of the emit command. Seems like they all do the same
//io.sockets.connected[connections[message.receiver].socket].emit("chat-message", message);
//io.to(connections[message.receiver].socket).emit("chat-message", message);
socket.broadcast.to(connections[message.receiver].socket).emit("chat-message", message);
} else {
console.log("Send push notification")
}
});
//Removing the socket on disconnect
socket.on('disconnect', function() {
console.log("The client disconnected");
for (var id in connections) {
if (connections[id].socket === socket.id) {
delete connections[id];
}
}
})
}
The "console.log(message);" in the messages handler is only called once. That's the confusing part for me. If the handler is called twice, why is this only printed once? Still, on the handler in my swift code, the handler for received messages is called multiple times.
I am using amqp-connection-manager given here
My code for reciever.js is as shown below :
var QUEUE_NAME = 'test';
var amqp = require('amqp-connection-manager');
// Handle an incomming message.
var onMessage = function (data) {
var message = JSON.parse(data.content.toString());
console.log("receiver: got message", message);
//channelWrapper.ack(data);
}
// Create a connetion manager
var connection = amqp.connect([process.env.CLOUDAMQP_MQTT_URL], {reconnectTimeInSeconds: 2, json: true});
connection.on('connect', function () {
console.log('Connected!');
});
connection.on('disconnect', function (params) {
console.log('Disconnected.', params.err.stack);
});
// Set up a channel listening for messages in the queue.
var channelWrapper = connection.createChannel({
setup: function (channel) {
// `channel` here is a regular amqplib `ConfirmChannel`.
return Promise.all([
channel.assertQueue(QUEUE_NAME, {durable: true}),
channel.prefetch(1),
channel.consume(QUEUE_NAME, onMessage)
]);
}
});
channelWrapper.waitForConnect()
.then(function () {
console.log("Listening for messages");
});
Now here whats happens is if I don't write channelWrapper.ack(data) , it stops receiving messages. So how can I enable receiving messages without writing channelWrapper.ack(data) .
That is because you are setting the prefetch value to 1. Prefetch is the number of unacknowledged messages you can have on a channel or on a queue (depends on the configuration) before receiving any more message.
You can change the prefetch value by changing this line in your code:
channel.prefetch(1)
With your current setup, you have to ack the messages eventually to be able to get more messages. If you are doing some async work with this message and acknowledge it later when the async work is done but do not want to wait for it to get other messages, you can just set the prefetch count to a reasonable amount.
If you are really sure that you don't need to ack the messages you can tell the broker not to expect an acknowledgement by noAck: true, just change this line:
channel.assertQueue(QUEUE_NAME, {durable: true, noAck: true})
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.
I have a rather simple Node.JS application that uses subscribe to redis to receive messages which it then sends out to the connected clients. In addition I also use the subscribe method to pass Node.JS the command to send out emails to our users.
All works well but the memory usage grows daily until it reaches 1.1GB (using command top on linux) and then all further email sending fails with the error message:
{ [Error: spawn ENOMEM] code: 'ENOMEM', errno: 'ENOMEM', syscall: 'spawn' }
Where could that come from? The source code is rather simple:
Clients connecting:
io.sockets.on('connection', function (socket) {
nClients++;
console.log("Number of clients connected " + nClients);
socket.on('disconnect', function () {
nClients--;
console.log("Number of clients remaining " + nClients);
});
});
Receiving messages to send out to the clients
cli_sub.on("message",function(channel,message) {
if(nUseDelay==1) {
oo = JSON.parse(message);
ablv_last_message[oo[0]["base"]+"_"+oo[0]["alt"]] = message;
} else {
io.sockets.emit('ablv', message);
}
});
Sending out emails to clients
cli_email.on("message",function(channel,message) {
var transport = nodemailer.createTransport("sendmail");
oo = JSON.parse(message);
var mailOptions = {
from: email_sender,
bcc: oo["bcc"],
to: oo["recipient"],
subject: oo["subject"],
html: oo["text"]
}
try {
transport.sendMail(mailOptions);
} catch(err) {
console.log(err);
}
});
setInterval(function() {
Object.keys(ablv_last_message).forEach( function(key) {
io.sockets.emit('ablv', ablv_last_message[key]);
});
ask_last_message = [];
}, 5000);
When you call nodemailer.createTransport you're creating a pool of SMTP connections that's intended to be reused for the life of your application.
So change your code to call that once at your app's startup and then reuse the transport object each time you need to send an email.
I implemented a node.js script that queries the APN Feedback service to retrieve the list of invalid tokens. Unfortunately, I did not manage to get any invalid token. I followed these steps:
Install the ios app with push notifications in sandbox mode.
Send some notifications to the app (done successfully).
Uninstall the app (I read that if the app that I uninstall is the only one with push notifications, it will cause the disconnection from the APN Service and make impossible to notify it that the app was uninstalled; but this is not my case, the iPad has many push notification apps installed!!).
Send many other notifications with the same token, about ten or twenty, just to prove that the application token is not valid anymore (obviously the notifications are not delivered because the app has just been uninstalled).
Query the Feedback service to finally get the invalid token. The
Feedback service does not send anything, it just closes the connection without any kind of data.
This is the script I use to query the feedback service:
function pollAPNFeedback() {
var certPem = fs.readFileSync('apns-prod-cert.pem', encoding='ascii');
var keyPem = fs.readFileSync('apns-prod-key-noenc.pem', encoding='ascii');
var options = { key: keyPem, cert: certPem };
console.log("Connecting APN feedback service");
var stream = tls.connect(2196, 'feedback.sandbox.push.apple.com', options, function() {
if (stream.authorized == false) {
return console.log('not connected')
} else {
console.log('connected');
};
var bufferlist = [];
stream.on('data', function(data) {
// APN feedback starts sending data immediately on successful connect
console.log('-->Data: ', data);
//bufferlist.push(data);
});
stream.on('readable', function(){
console.log('we have incoming data');
});
stream.on('error', function(err){
console.log('error: ', err);
});
stream.on('close', function(){
console.log('closed');
console.log('stream.data = ', stream.data);
});
});
}
As you can see, I put some listeners on the stream variable. The callback function on the 'data' listener is never invoked, only the 'close' event triggers its callback. I am sure that the connection is up because stream.authorized is true.
What am I doing wrong?
Is it possible that you are using a production certificate to contact the sandbox environment?
From your code :
var certPem = fs.readFileSync('apns-prod-cert.pem', encoding='ascii');
var keyPem = fs.readFileSync('apns-prod-key-noenc.pem', encoding='ascii');
And :
var stream = tls.connect(2196, 'feedback.sandbox.push.apple.com', options, function()
If that's the case, that's why it doesn't work.