1
votes

How do I setup the worker role to listen for server bus queue messages using the windows azure sdk ?

Currently I have this in my server.js worker role to listen for queue messages

var http = require('http')
    , config = require('./config')
    , azure = require('azure')
    , uuid = require('node-uuid');

http.createServer(function (req, res) {
    processServices(function () {
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.end('hello world');
    });
}).listen(process.env.port);

function processServices(callback) {
    var sb1 = azure.createServiceBusService(config.serviceBusNamespace, config.serviceBusAccessKey);
    sb1.receiveQueueMessage('startup', function (error, m) {
        if (!error) {
            writeMessage(JSON.stringify(m), function () {
                callback();
            });
        }
        else {
            writeMessage(JSON.stringify(error), function () {
                callback();
            });
        }
    });
}

function writeMessage(message, callback) {
    var serviceClient = azure.ServiceClient;
    var ts1 = azure.createTableService(serviceClient.DEVSTORE_STORAGE_ACCOUNT, serviceClient.DEVSTORE_STORAGE_ACCESS_KEY, serviceClient.DEVSTORE_TABLE_HOST);

    ts1.getTable('Messages', function (error) {
        if (error === null) {
            var messageEntity = {
                PartitionKey: '0',
                RowKey: uuid(),
                Message: message
            };

            ts1.insertEntity('Messages', messageEntity, function (error, newMessage) {
                callback();
            });
        }
        else callback();
    });
}

And this in my server.js web role to setup the queue

var sb1 = azure.createServiceBusService(config.serviceBusNamespace, config.serviceBusAccessKey);
sb1.getQueue('startup', function (error, queue) {
    if (error) {
        sb1.createQueueIfNotExists('startup', function (error, queue) {
            if (!error)
                console.log("created startup queue 1: " + JSON.stringify(queue) + "\n");
            else
                console.log("don't got startup queue 1: " + JSON.stringify(error) + "\n");
        });
    }
    else console.log("created startup queue 2: " + JSON.stringify(queue) + "\n");
});
sb1.getQueue('serialnumbers', function (error, queue) {
    if (error) {
        sb1.createQueueIfNotExists('serialnumbers', function (error, queue) {
            if (!error)
                console.log("created serialnumbers queue 1: " + JSON.stringify(queue) + "\n");
            else
                console.log("don't got serialnumbers queue 1: " + JSON.stringify(error) + "\n");
        });
    }
    else console.log("created serialnumbers queue 2: " + JSON.stringify(queue) + "\n");
});

And this in my web role index.js file to send a message to the queue

var azure = require('azure')
    , config = require('../utils/config');

exports.index = function (req, res) {
    var sb1 = azure.createServiceBusService(config.serviceBusNamespace, config.serviceBusAccessKey);
    var startupMessage = {
        body: ''
    };

    sb1.getQueue('startup', function (error, queue) {
        if (!error) {
            sb1.sendQueueMessage('startup', startupMessage, function (error) {
                if (!error) {
                    console.log("sent startup message 1\n");

                    res.render('index', {
                        locals: {
                            pageTitle: 'Home'
                        }
                    });
                }
                else {
                    console.log("didn't send startup message 1: " + JSON.stringify(error) + "\n");

                    res.render('index', {
                        locals: {
                            pageTitle: 'Home'
                        }
                    });
                }
            });
        }
        else {
            res.render('index', {
                locals: {
                    pageTitle: 'Home'
                }
            });
        }
    });
};

How do I get it so that the worker role listens and executes when the web role runs the index.js file?

Currently its not doing that, the messages are sitting in the queue but aren't being read by the worker role?

How do I get the worker role to read the message from the queue?

Should I run a cron job or use socket.io? I'm a little confused.

2

2 Answers

0
votes

Problem with npm azure package that it works via HTTP underneath, and as you know HTTP is request/response protocol. (Unfortunately in this application layer there is no things like SignalR or similar other "push" type communication). So the only way is to pull for messages -((.

But there is another way to consume (listen) for messages, if you use AMQP protocol.

There is npm package called amqp10 (promise-based, AMQP 1.0 compliant node.js client), there you subscribe to messages and start listen, concept similar to httpServer, or expressjs. On their npmjs package home page you find docs and samples.

In short it looks something like this: ..

async function sample( {connectionString, topicSubscriptionPath} ){
   const { Client, Policy } = require('amqp10');
   const client = new Client(Policy.Utils.RenewOnSettle(1, 1, Policy.ServiceBusTopic));
   const connection = await client.connect(connectionString);
   const receiver = await connection.createReceiver(topicSubscriptionPath);

   receiver.on('message', (message) => {
         try {
           // here is your brokered message, do whatever u need to do
           receiver.accept(message); //if can be marked as processed, aka can be deleted from service bus
         } catch (error) {
           this.receiver.reject(message); //return back to service bus
         }
       });
   }
sample(buildConnectionString(), 'subscriptionNameInYourTopic');

function buildConnectionString(){
  //very specific format, keys you can find in your azure subscription
   return `amqps://${sharedAccessKeyName}:${sharedAccessKey}@${queueEndpoint}`;
}
}
-1
votes

You just need continuously poll queue with .receiveQueueMessage method, until you receive the message from the queue. Time intervals between polls are completelly up to you.