You may have wondered what Azure Service Bus is all about and how you might use it. In a word, it is all about messaging.

With the advent of easy-to-implement “microservices” using cloud services like Azure Functions and Amazon Web Services Lambda, our systems are becoming collections of loosely coupled nodes that are easier to debug, test, and replace, while allowing more developers to work independently of each other.

The challenge is that these microservice components need to communicate with each other. While there are many ways to do this, a high speed, reliable messaging service like Azure Service Bus can be set up in minutes and scaled and managed with several advanced features.

This article will give you an introduction to the Azure Service Bus.

Queues and Topics

The two basic services of the Azure Service Bus are Queues and Topics.

Queues enable you to send messages in a simple first in, first out manner. With queues, there is one writer and one reader.

Topics offer more flexibility and enable one writer and many readers. This type of messaging service is sometimes called a publisher and subscriber or pub-sub service. In the simplest case, a topic with a single subscriber is functionally the same as a queue. The utility comes in having multiple subscribers working on either the same messages or a subset of messages determined by a filter. In this article, I will only show the simplest case.

To add filters to a subscription, so only a subset of messages is received, you must create the subscription in code. The portal does not support UI to set filters.

There are three filter types:

  • Boolean (true/false) SQL filter
  • SQL like statement using properties of the message
  • Correlation Filters which match against a set of conditions

Note that the default “filter” is true, meaning this subscriber will receive all messages.

Prerequisites

At a minimum, you will need an Azure account. A free trial is available if you do not already have an account.

Note that Azure Service Bus currently provides three pricing tiers: Basic, Standard And Premium. Queues are currently available in all three tiers, but topics are currently supported only on the Standard and Premium tiers. Refer to the Azure website for more details and the current pricing.

The samples here were written and tested using a C# “console” project in Visual Studio 2019 Version 16.0.4 and Microsoft.AzureServiceBus Version 3.4.0.

Service Bus Setup in Azure

There are several ways to create resources in Azure. The simplest is using the Azure web portal (https://portal.azure.com) and sign in with your account

The first step is to create a Service Bus namespace. The following parameters are required:

  • Name: This must be a unique service bus name across Azure as it is publicly facing.
  • Pricing: Select the Basic, Standard or Premium tier. For Topics and Subscriptions, you need Standard pricing.
  • Set Subscription, Resource group, and Location per your preferences.

Click on “create” to start the deployment of a new Service Bus namespace. The deployment may take a few minutes.

Click on the new namespace to show an overview. To get the connection string for this namespace, click on “Shared access policies” and then the “RootMagageSharedAccessKey”. Click on the clipboard icon of the “Primary Connection String”. You will need this connection string for each of the sample projects.

Queue Write Example

In your newly created service bus namespace, click on “+ Queue” in the header to add a new queue. The queue name only has to be unique within the Service Bus namespace. Use default values for the rest of the settings.

After the queue is created and deployed it will appear at the bottom of the namespace page. If you click on the new queue, the current status including the active message count (which should be zero) will be displayed.

Create a new Visual Studio project (Console App, .NET Core, C# is what I’m using) and name it SBQueueWriter.

In each project, you must add the NuGet package “Microsoft.Azure.ServiceBus” (not windows service bus).

This project will send two messages to the queue. Replace the code in the program.cs file with the code below. Be sure to replace the text in sbconnstr with the connection string from your Service Bus namespace.

using System;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Azure.ServiceBus;

namespace SBQueueWriter
{
    class Program
    {
        static IQueueClient queueClient;

        static async Task Main(string[] args)
        {
            var sbconnstr = "Use primary connection from your sb namespace";
            var qname = "sbqueue";

            await Task.Run(() =>
            {
                queueClient = new QueueClient(sbconnstr, qname);
                var messageCount = 2;

                try
                {
                    for (var i = 0; i < messageCount; i++)
                    {
                        string simpleJson = "{\"data\":\"" + i.ToString() + "\"}";

                        var sbMessage = new
Message(Encoding.UTF8.GetBytes(simpleJson));

                        Console.WriteLine(simpleJson);

                        queueClient.SendAsync(sbMessage);
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Error: " + ex.Message + ", " 
+ ex.StackTrace);
                }

                Console.ReadKey();

                queueClient.CloseAsync();
            });
        }
    }
}

Once you run this code without errors, go to the portal and refresh the queue and see that there are now two messages.

Queue Read Example

Add a new project SBQueueReader, add the code below, change the connection string, set as the startup project and run.

using System;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Azure.ServiceBus;

namespace SBQueueReader
{
    class Program
    {
        static IQueueClient queueClient;

        static async Task Main(string[] args)
        {
       var sbconnstr = "Use primary connection from your sb namespace";            
var qname = "sbqueue";

            await Task.Run(() =>
            {
                try
                {
                    queueClient = new QueueClient(sbconnstr, qname);

                    // Configure message handler, set the exception handler
                    // Default values are shown for illustration
                    var messageHandlerOptions = 
new MessageHandlerOptions(ExceptionHandler)
                    {
                        AutoComplete = false,
                        MaxAutoRenewDuration = new TimeSpan(0, 5, 0), // 5 minutes
                        MaxConcurrentCalls = 1,
                    };

                    // Register the function that will process messages
                    queueClient.RegisterMessageHandler(MessageProcessor,
messageHandlerOptions);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Error: " + ex.Message + ", " 
+ ex.StackTrace);
                }

                Console.ReadKey();

                queueClient.CloseAsync();
            });
        }

        static async Task MessageProcessor(Message message, 
CancellationToken token)
        {
            Console.WriteLine("Received message: " 
+ Encoding.UTF8.GetString(message.Body));
// complete the message
            await queueClient.CompleteAsync(message.SystemProperties.LockToken); 
        }
        static Task ExceptionHandler(
ExceptionReceivedEventArgs exReceivedEventArgs)
        {
            // The exception context reveals what happened!
            var exContext = exReceivedEventArgs.ExceptionReceivedContext;
            
            var msg = "Exception Endpoint: " + exContext.Endpoint 
+ ", Action: " + exContext.Action;
            Console.WriteLine(msg);

            return Task.CompletedTask;
        }
    }
}

Go to the portal and refresh; there should be no messages.

Topic Write Example

Create a topic by clicking on “+Topic” on the service bus namespace page. Use the defaults.

Now create a new subscription. Refresh the Service Bus namespace page and click on the “Topics” tab near the middle of the page to see your new topic displayed. Click on the topic.

Click on “sbtopic” and on the topic page click on “+Subscription” to make a new subscription, give it a name “sbtopicsubscription” and click on create.

Add a new project SBTopicWriter, add the code below, change the connection string, set as the startup project and run. Note that the default subscription has a default filter = true, that is all messages will be received.

using System;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Azure.ServiceBus;

namespace SBTopicWriter
{
    class Program
    {
        static ITopicClient topicClient;

        static async Task Main(string[] args)
        {
            var sbconnstr = "Use primary connection from your sb namespace";            var tname = "sbtopic";

            await Task.Run(() =>
            {
                topicClient = new TopicClient(sbconnstr, tname);
                var messageCount = 2;

                try
                {
                    for (var i = 0; i < messageCount; i++)
                    {
                        string simpleJson = "{\"data\":\"" + i.ToString() + "\"}";

                        var sbMessage = 
new Message(Encoding.UTF8.GetBytes(simpleJson));

                        Console.WriteLine(simpleJson);

                        topicClient.SendAsync(sbMessage);
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Error: " + ex.Message + ", " 
+ ex.StackTrace);
                }

                Console.ReadKey();

                topicClient.CloseAsync();
            });
        }
    }
}

Refresh the portal and see that the subscription has two messages.

Subscription Read Example

Add a new project SBSubscriptionReader, add the code below, change the connection string, set as the startup project and run.

using System;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Azure.ServiceBus;

namespace SBSubscriptionReader
{
    class Program
    {
        static ISubscriptionClient subClient;

        static async Task Main(string[] args)
        {
            var sbconnstr = "Use primary connection from your sb namespace";
            var tname = "sbtopic";
            var sname = "sbtopicsubscription";

            await Task.Run(() =>
            {
                try
                {
                    subClient = new SubscriptionClient(sbconnstr, tname, sname);

                    // Configure message handler
                    // Values are default but set for illustration
                    var messageHandlerOptions = 
new MessageHandlerOptions(ExceptionReceivedHandler)
                    {
                        AutoComplete = false,
                        // ExceptionReceivedHandler = set in constructor
                        MaxAutoRenewDuration = new TimeSpan(0, 5, 0), // 5 minutes
                        MaxConcurrentCalls = 1,
                    };

                    // Register the function that processes messages.
                    // Once set new message will be received
                    subClient.RegisterMessageHandler(ProcessMessagesAsync, 
messageHandlerOptions);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Error: " + ex.Message + ", " 
+ ex.StackTrace);
                }

                Console.ReadKey();

                subClient.CloseAsync();
            });
        }

        static async Task ProcessMessagesAsync(Message message, 
CancellationToken token)
        {
            // Process the message.
            Console.WriteLine("Received message: " 
+ Encoding.UTF8.GetString(message.Body));

            // This will complete the message, other options are availalbe
            await subClient.CompleteAsync(message.SystemProperties.LockToken); 

        }

        // Use handler to examine the exceptions received on the message pump.
        static Task ExceptionReceivedHandler(
ExceptionReceivedEventArgs exReceivedEventArgs)
        {
            // The exception context reveals what happened!
            var exContext = exReceivedEventArgs.ExceptionReceivedContext;
            var msg = "Exception Endpoint: " + exContext.Endpoint + ", Action: " 
+ exContext.Action;
            Console.WriteLine(msg);

            return Task.CompletedTask;
        }

    }
}

Refresh the portal and verify that the subscriber does not have any messages.

Summary

This article is a very basic introduction to the Azure Service Bus. You should now feel comfortable writing queues and topics and reading queues and subscriptions. There are many considerations and features that are beyond the scope of this article.

Once you try this and see how easy it is, passing messages will be easy.

How to work with us

  • Contact us to set up a call.
  • We will analyze your needs and recommend a content contract solution.
  • Sign on with ContentLab.
  • We deliver topic-curated, deeply technical content to you.

To get started, complete the form to the right to schedule a call with us.

Content Science Blog

Our blog devoted to the fundamentals of producing content and marketing to developers.

Ask a Developer Video Series

Our video series where developers answer questions about what makes for useful technical content.


Send this to a friend