因此,最近我需要使用Service Bus Topic and Subscriptions
,并且关注了许多文章和教程。我已经能够成功实现Microsoft的Get started with Service Bus topics,并且还成功地使用了Visual Studio 2017's
Worker Role
模板来访问数据库。
但是,我对如何正确地“组合”两者感到困惑。尽管Get started with Service Bus topics文章展示了如何创建2个应用程序,一个要发送,一个要接收然后退出,但Worker Role
模板似乎与await Task.Delay(10000);
不断循环。
我不确定如何正确地将两者“网格化”。本质上,我希望我的Worker Role
保持生命状态,并永远监听其订阅中的条目(或直到它明显退出为止)。
任何指导都很棒!
P.S .:如果您感兴趣,我曾在StackExchange - Software Engineering问过一个有关我应该用于我的案例的适当技术的相关问题。
更新#1(2018/08/09)
基于Arunprabhu's answer,这是一些基于我使用Message
的{{1}}模板阅读和接收的文章中如何发送Visual Studio 2017
的代码
发送(基于Get started with Service Bus topics)
Worker Role with Service Bus Queue
接收(基于using System;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Azure.ServiceBus;
namespace TopicsSender {
internal static class Program {
private const string ServiceBusConnectionString = "<your_connection_string>";
private const string TopicName = "test-topic";
private static ITopicClient _topicClient;
private static void Main(string[] args) {
MainAsync().GetAwaiter().GetResult();
}
private static async Task MainAsync() {
const int numberOfMessages = 10;
_topicClient = new TopicClient(ServiceBusConnectionString, TopicName);
Console.WriteLine("======================================================");
Console.WriteLine("Press ENTER key to exit after sending all the messages.");
Console.WriteLine("======================================================");
// Send messages.
await SendMessagesAsync(numberOfMessages);
Console.ReadKey();
await _topicClient.CloseAsync();
}
private static async Task SendMessagesAsync(int numberOfMessagesToSend) {
try {
for (var i = 0; i < numberOfMessagesToSend; i++) {
// Create a new message to send to the topic
var messageBody = $"Message {i}";
var message = new Message(Encoding.UTF8.GetBytes(messageBody));
// Write the body of the message to the console
Console.WriteLine($"Sending message: {messageBody}");
// Send the message to the topic
await _topicClient.SendAsync(message);
}
} catch (Exception exception) {
Console.WriteLine($"{DateTime.Now} :: Exception: {exception.Message}");
}
}
}
}
模板)
Worker Role with Service Bus Queue
更新#2(2018/08/10)
在Arunprabhu提出了一些建议之后,并且知道我正在使用其他库,下面是我目前的解决方案,其中的内容来自多个来源。有什么我要忽略的东西吗?当前遇到的错误可能是另一个问题或已经回答,因此不希望在进一步研究之前发布它。
using System;
using System.Diagnostics;
using System.Net;
using System.Threading;
using Microsoft.ServiceBus.Messaging;
using Microsoft.WindowsAzure.ServiceRuntime;
namespace WorkerRoleWithSBQueue1 {
public class WorkerRole : RoleEntryPoint {
// The name of your queue
private const string ServiceBusConnectionString = "<your_connection_string>";
private const string TopicName = "test-topic";
private const string SubscriptionName = "test-sub1";
// QueueClient is thread-safe. Recommended that you cache
// rather than recreating it on every request
private SubscriptionClient _client;
private readonly ManualResetEvent _completedEvent = new ManualResetEvent(false);
public override void Run() {
Trace.WriteLine("Starting processing of messages");
// Initiates the message pump and callback is invoked for each message that is received, calling close on the client will stop the pump.
_client.OnMessage((receivedMessage) => {
try {
// Process the message
Trace.WriteLine("Processing Service Bus message: " + receivedMessage.SequenceNumber.ToString());
var message = receivedMessage.GetBody<byte[]>();
Trace.WriteLine($"Received message: SequenceNumber:{receivedMessage.SequenceNumber} Body:{message.ToString()}");
} catch (Exception e) {
// Handle any message processing specific exceptions here
Trace.Write(e.ToString());
}
});
_completedEvent.WaitOne();
}
public override bool OnStart() {
// Set the maximum number of concurrent connections
ServicePointManager.DefaultConnectionLimit = 12;
// Initialize the connection to Service Bus Queue
_client = SubscriptionClient.CreateFromConnectionString(ServiceBusConnectionString, TopicName, SubscriptionName);
return base.OnStart();
}
public override void OnStop() {
// Close the connection to Service Bus Queue
_client.Close();
_completedEvent.Set();
base.OnStop();
}
}
}
答案 0 :(得分:2)
考虑到更新后的问题Update#1(2018/08/09)的复杂性,我提供了一个单独的答案。
发送者和接收者正在使用不同的库。
发件人-Microsoft.Azure.ServiceBus
Microsoft.Azure.ServiceBus的消息对象为Message,其中WindowsAzure.ServiceBus具有BrokeredMessage。
Microsoft.Azure.ServiceBus中有一种方法RegisterMessageHandler,这是WindowsAzure.ServiceBus中client.OnMessage()的替代方法。通过使用此方法,侦听器将消息作为Message对象接收。该库支持您期望的异步编程。
有关两个库的示例,请参考here。
答案 1 :(得分:1)
如果使用的是Visual Studio,则存在一个默认模板,可用于使用Service Bus Queue创建Azure Cloud Service和辅助角色。在那里,您需要使用WorkerRole.cs中的SubscriptionClient更改QueueClient。
然后,辅助角色将保持活动状态,侦听主题订阅中的消息。
您可以找到示例here。您应该在Cloud Service中使用Service Bus Queue创建Worker角色
答案 2 :(得分:0)
我想知道您是否有选择Web作业上的工作者角色的特定原因?如果没有,您可以使用具有ServiceBusTrigger属性的Web作业,它将使您的代码更简单。 more info here...