我正在使用此代码接收来自队列的消息:
function startReceiver(){
serviceBusService.getQueue(configurations.queueForRequest, function(err, queue){
if(!err){
var length = queue.CountDetails['d2p1:ActiveMessageCount'];//get count of active messages
if(length > 0) {
serviceBusService.receiveQueueMessage(configurations.queueForRequest, {isPeekLock:true},
function(error, lockedMessage){ HandleMessage(error, lockedMessage) });
return; //get out from this method
}
}
else{
console.log('Can not get queue');
}
setTimeout(startReceiver, 3000);//if err or there are no messages then call this method later
});
}
function handleMessage(err, msg){
var result;
if (!err){
serviceBusService.deleteMessage(msg, function(deleteError){
if(deleteError) {
console.log('Can not delete the message')
}
else{
console.log('Msg has been deleted');
}
});//delete the message which has been received
try{
result = GetResult(msg.body)
}
catch (er){
result = GetResultWhenExp();
}
finally{
sendMessage(result); //send a response
startReceiver(); //repeat a receiver loop
}
}//!error
else{console.log('Error occured: '+err);
setTimeout(startReceiver, 3000); //repeat a receiver loop later
}
}
问题是当handleMessage()仅在第一次运行时我可以收到消息。进一步的startReceiver()可以获得正确的活动消息计数,但handleMessage()获取未定义的msg作为参数始终(即serviceBusService.receiveQueueMessage()失败,错误是“没有要接收的消息”)。
使用C#库及其标准功能来接收消息,效果很好。
这里有什么问题?请帮忙
编辑:我只是从azure-sdk-for-node存储库中复制粘贴this example,在我的情况下,它会产生相同的行为:第一条消息已成功收到,但是请求后续到总线返回“没有要接收的消息”
答案 0 :(得分:1)
目前,我可以提出您的问题,并检测到它应该是某种复杂场景中的性能问题,该场景与Peek-Lock
模式相关,以便从队列接收消息。
在您的代码段中,您使用deleteMessage()
模式接收消息,这将锁定队列的第一条消息(作为队列传递消息FIFO),作为handleMessage()
中的startReceiver()
函数是一个asyn函数,因此node.js不会等待此结果,会立即调用finally
部分中的startReceiver()
。在这种情况下,它可能会尝试接收锁定的消息并出现此问题。
您可以尝试两种操作来解决此问题:
finally
部分下的setTimeout(startReceiver, 3000);
修改为read and delete
receiveQueueMessage(quene_name,callback)
接收模式,使用receiveQueueMessage(quene_name,{ isPeekLock: true },callback)
代替 ac.sumPer=((ac.sum/5)*100);
ac.test='p'+ac.sumPer;
console.log(ac.test);
$('#change').addClass("c100 big dark ac.test");
答案 1 :(得分:0)
最后我找到了解决这个问题的方法。
起初我认为原因是Node.js的Azure包已经过时了。 但事实并非如此。
当我手动创建队列时,即通过azure portal我的node.js客户端工作错误(它无法接收消息)。
当使用代码(createQueueIfNotExists
方法)创建它时,没有任何问题。
它为我工作但我对此行为的细节一无所知,我向他们询问了这个团队。
答案 2 :(得分:0)
这是因为,默认情况下,从天蓝色门户网站创建新队列时,会选中“分区”复选框。创建队列之前,请取消选中“分区”复选框。
由于某些原因,当从队列中读取消息时,节点客户端似乎从随机分区中抢夺。您将从空的分区中获得“无消息可接收”错误。我找不到任何说明如何将sdk节点与分区队列一起使用的文档。
编辑:
以下是一些说明分区的文档: https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-partitioning
经过一番挖掘,我发现其余客户端(节点客户端使用的节点)不支持会话,换句话说,当您从队列中读取消息时,您无法告诉客户端要使用哪个分区。