简体   繁体   English

在工作角色中运行服务总线队列消息的Azure Node.js

[英]Azure Node.js Running Service Bus Queue Messages in Worker Role

How do I setup the worker role to listen for server bus queue messages using the windows azure sdk ? 如何设置辅助角色以使用Windows Azure sdk侦听服务器总线队列消息?

Currently I have this in my server.js worker role to listen for queue messages 目前,我在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();
    });
}

And this in my server.js web role to setup the queue 这是在我的server.js网络角色中设置队列的

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 而这在我的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'
                }
            });
        }
    });
};

How do I get it so that the worker role listens and executes when the web role runs the index.js file? 如何获取它,以便当Web角色运行index.js文件时,辅助角色可以侦听并执行?

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? 我应该运行cron作业还是使用socket.io? I'm a little confused. 我有点困惑。

You just need continuously poll queue with .receiveQueueMessage method, until you receive the message from the queue. 您只需要使用.receiveQueueMessage方法连续轮询队列,直到从队列接收消息即可。 Time intervals between polls are completelly up to you. 两次轮询之间的时间间隔完全取决于您。

Problem with npm azure package that it works via HTTP underneath, and as you know HTTP is request/response protocol. npm azure软件包存在问题,该软件包可通过下面的HTTP起作用,并且您知道HTTP是请求/响应协议。 (Unfortunately in this application layer there is no things like SignalR or similar other "push" type communication). (不幸的是,在此应用程序层中没有诸如SignalR之类的东西或类似的其他“推送”类型的通信)。 So the only way is to pull for messages -((. 因此,唯一的方法是提取消息-((。

But there is another way to consume (listen) for messages, if you use AMQP protocol. 但是,如果您使用AMQP协议,则还有另一种消费(监听)消息的方法。

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. 有一个称为amqp10 (基于承诺,符合AMQP 1.0的node.js客户端)的npm软件包,您可以在其中订阅消息并开始侦听,其概念类似于httpServer或expressjs。 On their npmjs package home page you find docs and samples. 在他们的npmjs软件包主页上,您可以找到文档和示例。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM