Implementing Azure Service Bus for messaging and queuing

Introduction

Azure Service Bus is a messaging service that you can use to communicate between applications and services in a cloud-based environment. It provides a reliable and secure way to send and receive messages using different messaging patterns, such as publish-subscribe, point-to-point, and request-response.

In this tutorial, we will cover the basics of Azure Service Bus and show you how to implement it in a .NET application for messaging and queuing. Specifically, we will show you how to create an Azure Service Bus namespace, create a queue, send and receive messages, and handle dead-letter messages.

Prerequisites

Before you can start implementing Azure Service Bus in your .NET application, you need to have the following:

  • An active Azure subscription
  • A Visual Studio environment (you can use any version as long as it supports .NET Framework 4.7 and above)

Setting up Azure Service Bus Namespace

The first step is to set up an Azure Service Bus namespace. This namespace will be used to group and manage your messaging entities, such as queues, topics, and subscriptions.

To set up a Service Bus namespace:

  1. Log in to the Azure portal and click on “Create a resource” in the left-hand side menu.
  2. Search for “Service Bus” and select it from the list of services.

  3. In the “Service Bus” pane, click on “Create.”

  4. You will be prompted to fill in the following details:

  • Subscription: Choose the subscription you want to use for the Service Bus namespace.
  • Resource group: Choose a resource group or create a new one.
  • Name: Choose a unique name for your Service Bus namespace.
  • Location: Choose the location where you want to create the Service Bus namespace.
  1. Click on “Create” to create the Service Bus namespace.

It may take a few minutes for the Service Bus namespace to be created. Once it is created, you can view it in the Azure portal.

Creating a Queue in Azure Service Bus

After setting up your Service Bus namespace, the next step is to create a queue. A queue is a messaging entity that provides a way for applications to send and receive messages asynchronously.

To create a queue in Azure Service Bus:

  1. In the Azure portal, navigate to your Service Bus namespace and click on “Queues” in the left-hand side menu.
  2. Click on “New queue” to create a new queue.

  3. You will be prompted to fill in the following details:

  • Name: Choose a unique name for your queue.
  • Size: Choose the maximum size for your queue.
  1. Click on “Create” to create the queue.

Sending Messages to Azure Service Bus Queue

Once you have created a queue, you can start sending messages to it. In this section, we will show you how to send messages to an Azure Service Bus queue from your .NET application.

  1. Open Visual Studio and create a new console application.
  2. Add the following NuGet packages to your project:

  • Microsoft.Azure.ServiceBus
  • Newtonsoft.Json

You can add these packages using the NuGet Package Manager in Visual Studio.

  1. Create a class that represents the message you want to send. For example:
public class Order
{
    public int OrderId { get; set; }
    public string ProductName { get; set; }
    public decimal Price { get; set; }
}
  1. In your console application, add the following code to send a message to your queue:
var serviceBusConnectionString = "your_connection_string";
var queueName = "your_queue_name";

var order = new Order { OrderId = 1, ProductName = "Product 1", Price = 9.99m };
var messageBody = JsonConvert.SerializeObject(order);

var message = new Message(Encoding.UTF8.GetBytes(messageBody));
message.UserProperties.Add("OrderId", order.OrderId);

var queueClient = new QueueClient(serviceBusConnectionString, queueName);
queueClient.SendAsync(message).GetAwaiter().GetResult();

In the code above, we first create an instance of the Order class and serialize it into a JSON string. We then create a new Message instance with the message body and add a user property for the order ID. Finally, we create a QueueClient instance and call the SendAsync method to send the message to the queue.

Make sure to replace your_connection_string and your_queue_name with your own Service Bus connection string and queue name.

Receiving Messages from Azure Service Bus Queue

After sending messages to your queue, you can start receiving them in your .NET application. In this section, we will show you how to receive messages from an Azure Service Bus queue.

  1. Add the following code to your console application to receive a message from your queue:
var serviceBusConnectionString = "your_connection_string";
var queueName = "your_queue_name";

var queueClient = new QueueClient(serviceBusConnectionString, queueName);
var messageHandlerOptions = new MessageHandlerOptions(ExceptionReceivedHandler)
{
    MaxConcurrentCalls = 1,
    AutoComplete = false
};

queueClient.RegisterMessageHandler(ProcessMessagesAsync, messageHandlerOptions);

Console.ReadLine();

await queueClient.CloseAsync();

In the code above, we create a new QueueClient instance and register a message handler with options. We then call the RegisterMessageHandler method to start listening for messages on the queue.

  1. Add the following method to your code to process the received message:
private static async Task ProcessMessagesAsync(Message message, CancellationToken token)
{
    var messageBody = Encoding.UTF8.GetString(message.Body);
    var order = JsonConvert.DeserializeObject<Order>(messageBody);

    Console.WriteLine($"Received Order with ID={order.OrderId}");

    await queueClient.CompleteAsync(message.SystemProperties.LockToken);
}

In the code above, we first retrieve the message body as a string and deserialize it into an Order instance using Newtonsoft.Json. We then display the order ID in the console and call the CompleteAsync method to mark the message as completed and remove it from the queue.

  1. Add the following method to your code to handle any exceptions that occur while receiving messages:
private static Task ExceptionReceivedHandler(ExceptionReceivedEventArgs e)
{
    Console.WriteLine($"Message handler encountered an exception {e.Exception}.");
    var context = e.ExceptionReceivedContext;
    Console.WriteLine("Exception context for troubleshooting:");
    Console.WriteLine($"- Endpoint: {context.Endpoint}");
    Console.WriteLine($"- Entity Path: {context.EntityPath}");
    Console.WriteLine($"- Executing Action: {context.Action}");
    return Task.CompletedTask;
}

In the code above, we simply display the exception and context information in the console.

Handling Dead-Letter Messages

In some cases, a message in your queue may be deemed undeliverable and will be moved to a dead-letter queue. Dead-letter queues help you identify and troubleshoot messages that could not be delivered due to issues such as incorrect addresses, exceeded TTL, or exceeding the queue length.

To handle dead-letter messages, you need to create a dead-letter queue and update your message handler to process dead-letter messages.

To create a dead-letter queue in Azure Service Bus:

  1. In the Azure portal, navigate to your Service Bus namespace and click on “Queues” in the left-hand side menu.
  2. Click on your queue to open its details page.

  3. In the “Settings” pane, click on “Dead-letter queue” and then click on “Enable.”

  4. You will be prompted to enter a name for your dead-letter queue.

  5. Click on “Create” to create the dead-letter queue.

After creating the dead-letter queue, update your message handler to process dead-letter messages by adding the following code:

private static async Task ProcessDeadLetterMessagesAsync(Message message, CancellationToken token)
{
    var messageBody = Encoding.UTF8.GetString(message.Body);
    var order = JsonConvert.DeserializeObject<Order>(messageBody);

    Console.WriteLine($"Received Order with ID={order.OrderId} from Dead-Letter Queue");

    await queueClient.CompleteAsync(message.SystemProperties.LockToken);
}

In the code above, we create a new method that processes dead-letter messages in the same way as regular messages. To register this method as the handler for dead-letter messages, update the MessageHandlerOptions to include the DeadLetterError property:

var messageHandlerOptions = new MessageHandlerOptions(ExceptionReceivedHandler)
{
    MaxConcurrentCalls = 1,
    AutoComplete = false,
    DeadLetterError = ExceptionReceivedHandler,
};

After making these changes, your message handler will be able to process both regular and dead-letter messages.

Conclusion

In this tutorial, we showed you how to implement Azure Service Bus in a .NET application for messaging and queuing. Specifically, we covered how to create a Service Bus namespace, create a queue, send and receive messages, and handle dead-letter messages.

Azure Service Bus provides a powerful and easy-to-use way for applications to communicate in a cloud-based environment. By understanding the basics of Azure Service Bus and following the steps outlined in this tutorial, can start your own applications.

Related Post