Azure Node.js在辅助角色中运行服务总线队列消息

时间:2012-07-30 10:17:11

标签: node.js azure

如何设置worker角色以使用windows azure sdk侦听服务器总线队列消息?

目前我在我的server.js辅助角色中有这个来侦听队列消息

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();
    });
}

这在我的server.js web角色中设置队列

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");
});

这在我的web角色index.js文件中向队列发送消息

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'
                }
            });
        }
    });
};

如何在Web角色运行index.js文件时监听并执行worker角色?

目前它没有这样做,消息是否在队列中但工作者角色没有读取?

如何让worker角色从队列中读取消息?

我应该运行cron作业还是使用socket.io?我有点困惑。

2 个答案:

答案 0 :(得分:0)

您只需要使用.receiveQueueMessage方法连续轮询队列,直到您从队列中收到消息。民意调查之间的时间间隔完全取决于您。

答案 1 :(得分:0)

npm azure 软件包存在的问题,该问题通过HTTP底层运行,并且您知道HTTP是请求/响应协议。 (不幸的是,在此应用程序层中没有诸如SignalR之类的东西或类似的其他“推送”类型的通信)。因此,唯一的方法是提取消息-((。

但是,如果使用AMQP协议,则还有另一种消费(监听)消息的方法。

有一个名为amqp10的npm程序包(基于承诺,符合AMQP 1.0的node.js客户端),您可以在其中订阅消息并开始侦听,其概念类似于httpServer或expressjs。在他们的npmjs软件包主页上,您可以找到文档和示例。

简而言之,它看起来像这样: ..

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}`;
}
}