SteGriff

Blog

Next & Previous

Azure Service Bus Topics in .Net Framework 4

I’ve done queue processing wrong a few times in my career. I can admit to that. I’ve made a lot of use of Azure Storage Queues because they’re extremely cheap (you pay for the storage only, which is about 7p/GB/month at globe-scale) and very easy to integrate.

Thing is, sometimes a queue doesn’t actually do everything you think it does. If you make a simple queue and expect two different services to both process messages from it, you’re going to have a bad time. That’s because you’re actually looking for a Topic, and the pub-sub model.

Hey, I started writing this a few weeks ago and dropped it. I’ve picked up the bits that matter and cut the post a little short just to get it out, so it’s a little specific. If you got here by Google, perhaps it’s just what you’re looking for! :)

Creating a Service Bus

Easy enough in the Azure portal. Navigate to the ‘Service Bus’ resource type, and go through the create process.

Things to note:

Nuget packages for integrating Service Bus

The pertinent Nuget packages for Service Bus are:

The docs examples are good at using the new Nuget package. Here’s a nice entry point to the new docs for getting started with service bus queues.

You might need to dig through the package archives if you are using an old .Net framework version:

.Net version Newest package version
Core 2+ Latest*
Fx 4.6.2 Latest*
Fx 4.6.1 https://www.nuget.org/packages/Microsoft.Azure.ServiceBus/3.4.0
Fx 4.6 https://www.nuget.org/packages/WindowsAzure.ServiceBus/5.0.0
Fx 4.5.2 https://www.nuget.org/packages/WindowsAzure.ServiceBus/4.1.11
Fx 4.5 https://www.nuget.org/packages/WindowsAzure.ServiceBus/4.1.3

*Note that as the newest package versions target .Net Standard 2.0, that equals support for .Net Core 2+ as well as .Net Fx 4.6.1+, but if you don’t want to pull down the universe of .Net Core compatibility libraries, the last version to explicitly target .Net Fx 4.6.1 is listed above. See the MS .Net Standard page for info.

Hierarchy of service bus concepts

Subscriptions are what makes it possible for more than one consumer to process a topic message. Messages are published to the topic, but they are consumed from the subscriptions, each of which has a copy of the message.

Get a connection string

To get a connection string, you need to go to your Service Bus in the Azure portal, go to Shared Access Signatures, and generate a signature with the privileges you need: Write, Listen, or Manage (manage is basically admin, and can both write and listen as well as create new topic subscriptions etc.)

Using Service Bus with a Topic in a .Net Framework 4.5 app

There’s a wealth of tutorials on the new library for .Net core. Let’s say I’m limited to using .Net 4.5.

I could make a solution with three projects; a sender console app, a receiver console app, and a common library containing the message class (to be shared by sender and receiver).

Sender

Every time the user presses Return, it will generate an instance of our shared PolicyMessage class and send it to the topic:

using Microsoft.ServiceBus.Messaging;

static void Main(string[] args)
{
	// Create a policy Application message
	// and send it to the topic

	var policyTopicSendConnectionString = "Endpoint=sb://sg-psl-apply.servicebus.windows.net/;SharedAccessKeyName=policytopicsend;SharedAccessKey=..........;EntityPath=policies";

	var topicClient = TopicClient.CreateFromConnectionString(policyTopicSendConnectionString);

	while(true)
	{
		var policyMessage = new PolicyMessage();
		topicClient.Send(new BrokeredMessage(policyMessage));
		Console.WriteLine("Sent: " + policyMessage.ToString());
		Console.WriteLine("Press return to send another.");
		Console.ReadLine();
	}
}

Receiver

Sets up a delegate that fires any time a message comes in. We unwrap our PolicyMessage from inside the BrokeredMessage using .GetBody<T>.

Setting AutoComplete to false allows us to choose programatically when to mark a message as processed.

using Microsoft.ServiceBus.Messaging;

static void Main(string[] args)
{
	// Read all Policy Application Messages
	// and write them to screen

	var policyTopicMasterConnectionString = "Endpoint=sb://sg-psl-apply.servicebus.windows.net/;SharedAccessKeyName=policytopicmaster;SharedAccessKey=..........";

	Action<BrokeredMessage> onMessage = (bm) => {
		var message = bm.GetBody<PolicyMessage>();
		Console.WriteLine(message.ToString());
	};

	var subClient = SubscriptionClient.CreateFromConnectionString(policyTopicMasterConnectionString, "policies", "applications");
	var options = new OnMessageOptions()
	{
		AutoComplete = false
	};
	subClient.OnMessage(onMessage, options);
	
	Console.WriteLine("End of receiver program");
	Console.ReadLine();
}

Some examples you’ll see elsewhere make use of MessagingFactory but this didn’t work for me. I think it’s because it doesn’t give you the facility to pick a particular subscription, only a topic:

var messagingFactory = MessagingFactory.CreateFromConnectionString(policyTopicMasterConnectionString);
var receiver = messagingFactory.CreateMessageReceiver("policies");
receiver.OnMessage(onMessage, options);

Further reading

You can check out this piece about how Azure Storage Queues and Azure Service Bus Queues differ.

Build cool stuff, fix old stuff!