我有一个应用程序,可以在过程的一部分中以JSON格式将消息写入Azure服务总线队列。我有一个下游进程,我想将该消息从队列中弹出,将json转换为对象,然后处理该对象。
我将消息推送到队列没有问题,但是我找不到一次或循环将消息从队列弹出的任何示例。我在Microsoft或Github上看到的每个示例都是一个控制台应用程序(在Web应用程序中无用),它设置某种侦听器,以侦听队列中的所有消息并编写一条控制台消息。我没有发现弹出消息然后对数据进行一些处理的示例。有没有人有示例说明如何从队列中弹出一条消息,然后对其进行处理或调用另一种方法来对消息中的数据进行处理?
更新: 我使用了下面的由Guru Pasupathy提供的WindowsAzure.ServiceBus示例,并使用了Azure Service Bus Queues: How To Read Individual Messages From A Queue中的以下代码片段来从BrokeredMessage对象获取消息文本:
Stream stream = message.GetBody<Stream>();
StreamReader reader = new StreamReader(stream);
string messageBody = reader.ReadToEnd();
然后我可以使用messageBody并将嵌入的JSON反序列化为POCO对象,然后就可以了!现在,我可以在应用程序中更有效地使用队列来执行各种任务。
答案 0 :(得分:1)
您可以使用“窥视锁定”接收模式从队列中获取消息,进行处理,然后根据您的业务逻辑选择“放弃”或“完成”。
如果您使用 WindowsAzure.ServiceBus nuget包发送/接收消息,则可以使用以下方法基于循环或单个调用从队列中逐个使用消息,而不必使用监听器。
public void Receive()
{
QueueClient myQueueClient = QueueClient.CreateFromConnectionString("<connectionString>;<queueName>", ReceiveMode.PeekLock);
int someCount = 2; //some random value for testing
try
{
for (int i = 0; i < someCount; i++)
{
BrokeredMessage message = myQueueClient.Receive();
Console.WriteLine("The message is " + message);
message.Complete();
}
}
catch(Exception e)
{
//Handle your expection
}
}
如果您使用的是 Microsoft.Azure.Service nuget包,那么我将无法找到一种不使用侦听器而仅读取一条消息的直接方法。我看到侦听器将继续轮询和处理队列,直到没有更多消息为止。
如果您要停止轮询并继续获取所有可用消息,那么作为一种解决方法,您可以在读取一条消息后关闭QueueClient实例,并在过程准备好接收下一条消息时打开qc并注册处理程序
public async Task ProcessMessagesAsync(Message message, CancellationToken token)
{
Console.WriteLine($"Received message: {Encoding.UTF8.GetString(message.Body)}");
BinaryFormatter bf = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream(message.Body))
{
Payload payload = (Payload) bf.Deserialize(ms);
//Based on your needs you may have a condition here based on which you could Abandon or Complete the mesage
await qc.CompleteAsync(message.SystemProperties.LockToken);
Console.WriteLine("Completed the message --> " + payload.Message + " -- Id --> " + payload.Id);
//await qc.AbandonAsync(message.SystemProperties.LockToken);
//Console.WriteLine("Abandon the message --> " + payload.Message + " -- Id --> " + payload.Id);
qc.CloseAsync(); //If you close the QueueClient instance here, no more messages will be picked up from queue.
}
}
以上示例基于https://docs.microsoft.com/en-us/azure/service-bus-messaging/service-bus-dotnet-get-started-with-queues#receive-messages-from-the-queue,我只是在最后添加了qc.CloseAsync()调用。没有此行,侦听器将继续处理,直到队列中没有剩余消息为止。我不确定是否有更好的方法可以实现这一目标,但我想共享。
希望这会有所帮助
编辑-
发送消息时,如果您使用的是自定义类型,则可以使用以下内容
BrokeredMessage message = new BrokeredMessage(new Payload() { Id = 4332, Message = "WindowsAzure package" });
myQueueClient.Send(message);
在接收时,应使用GetBody,如下所示
BrokeredMessage message = myQueueClient.Receive();
var incoming = message.GetBody<Payload>();
Console.WriteLine("The message is " + incoming.Id + " and " + incoming.Message);
message.Complete();
下面是供您参考的自定义对象
[Serializable]
public class Payload
{
public int Id { get; set; }
public string Message { get; set; }
}
同样适用于字符串
在收到您可以使用的同时
var incoming = message.GetBody<string>();
发送时,您可以发送
BrokeredMessage message = new BrokeredMessage("WindowsAzure package" );
您将在以下链接上获得有关不同内容格式的更多详细信息 https://abhishekrlal.com/2012/03/30/formatting-the-content-for-service-bus-messages/