Quickstart: Use Azure portal to create a Service Bus queue

This quickstart describes how to send and receive messages to and from a Service Bus queue, using the Azure portal to create a messaging namespace and a queue within that namespace, and to obtain the authorization credentials on that namespace. The procedure then shows how to send and receive messages from this queue using the .NET Standard library.

What are Service Bus queues?

Service Bus queues support a brokered messaging communication model. When using queues, components of a distributed application do not communicate directly with each other; instead they exchange messages via a queue, which acts as an intermediary (broker). A message producer (sender) hands off a message to the queue and then continues its processing. Asynchronously, a message consumer (receiver) pulls the message from the queue and processes it. The producer does not have to wait for a reply from the consumer in order to continue to process and send further messages. Queues offer First In, First Out (FIFO) message delivery to one or more competing consumers. That is, messages are typically received and processed by the receivers in the order in which they were added to the queue, and each message is received and processed by only one message consumer.

QueueConcepts

Service Bus queues are a general-purpose technology that can be used for a wide variety of scenarios:

  • Communication between web and worker roles in a multi-tier Azure application.
  • Communication between on-premises apps and Azure-hosted apps in a hybrid solution.
  • Communication between components of a distributed application running on-premises in different organizations or departments of an organization.

Using queues enables you to scale your applications more easily, and enable more resiliency to your architecture.

Prerequisites

To complete this tutorial, make sure you have installed:

Create a namespace in the Azure portal

To begin using Service Bus messaging entities in Azure, you must first create a namespace with a name that is unique across Azure. A namespace provides a scoping container for addressing Service Bus resources within your application.

To create a namespace:

  1. Sign in to the Azure portal

  2. In the left navigation pane of the portal, select + Create a resource, select Integration, and then select Service Bus.

    Create a resource -> Integration -> Service Bus

  3. In the Create namespace dialog, do the following steps:

    1. Enter a name for the namespace. The system immediately checks to see if the name is available. For a list of rules for naming namespaces, see Create Namespace REST API.

    2. Select the pricing tier (Basic, Standard, or Premium) for the namespace. If you want to use topics and subscriptions, choose either Standard or Premium. Topics/subscriptions are not supported in the Basic pricing tier.

    3. If you selected the Premium pricing tier, follow these steps:

      1. Specify the number of messaging units. The premium tier provides resource isolation at the CPU and memory level so that each workload runs in isolation. This resource container is called a messaging unit. A premium namespace has least one messaging unit. You can select 1, 2, or 4 messaging units for each Service Bus Premium namespace. For more information, see Service Bus Premium Messaging.
      2. Specify whether you want to make the namespace zone redundant. The zone redundancy provides enhanced availability by spreading replicas across availability zones within one region at no additional cost. For more information, see Availability zones in Azure.
    4. For Subscription, choose an Azure subscription in which to create the namespace.

    5. For Resource group, choose an existing resource group in which the namespace will live, or create a new one.

    6. For Location, choose the region in which your namespace should be hosted.

    7. Select Create. The system now creates your namespace and enables it. You might have to wait several minutes as the system provisions resources for your account.

      Create namespace

  4. Confirm that the service bus namespace is deployed successfully. To see the notifications, select the bell icon (Alerts) on the toolbar. Select the name of the resource group in the notification as shown in the image. You see the resource group that contains the service bus namespace.

    Deployment alert

  5. On the Resource group page for your resource group, select your service bus namespace.

    Resource group page - select your service bus namespace

  6. You see the home page for your service bus namespace.

    Home page for your service bus namespace

Get the connection string

Creating a new namespace automatically generates an initial Shared Access Signature (SAS) rule with an associated pair of primary and secondary keys that each grant full control over all aspects of the namespace. See Service Bus authentication and authorization for information about how to create rules with more constrained rights for regular senders and receivers. To copy the primary and secondary keys for your namespace, follow these steps:

  1. Click All resources, then click the newly created namespace name.

  2. In the namespace window, click Shared access policies.

  3. In the Shared access policies screen, click RootManageSharedAccessKey.

    connection-info

  4. In the Policy: RootManageSharedAccessKey window, click the copy button next to Primary Connection String, to copy the connection string to your clipboard for later use. Paste this value into Notepad or some other temporary location.

    connection-string

  5. Repeat the previous step, copying and pasting the value of Primary key to a temporary location for later use.

Create a queue in the Azure portal

  1. On the Service Bus Namespace page, select Queues in the left navigational menu.

  2. On the Queues page, select + Queue on the toolbar.

  3. Enter a name for the queue, and leave the other values with their defaults.

  4. Now, select Create.

    Queues -> + Queue -> Enter name -> Create

Send and receive messages

After the namespace and queue are provisioned, and you have the necessary credentials, you are ready to send and receive messages. You can examine the code in this GitHub sample folder.

To run the code, do the following:

  1. Clone the Service Bus GitHub repository by issuing the following command:

    git clone https://github.com/Azure/azure-service-bus.git
    
  2. Navigate to the sample folder azure-service-bus\samples\DotNet\GettingStarted\BasicSendReceiveQuickStart\BasicSendReceiveQuickStart.

  3. Copy the connection string and queue name you obtained in the Obtain the management credentials section.

  4. At a command prompt, type the following command:

    dotnet build
    
  5. Navigate to the bin\Debug\netcoreapp2.0 folder.

  6. Type the following command to run the program. Be sure to replace myConnectionString with the value you previously obtained, and myQueueName with the name of the queue you created:

    dotnet BasicSendReceiveQuickStart.dll -ConnectionString "myConnectionString" -QueueName "myQueueName"
    
  7. Observe 10 messages being sent to the queue, and subsequently received from the queue:

    program output

Clean up resources

You can use the portal to remove the resource group, namespace, and queue.

Understand the sample code

This section contains more details about what the sample code does.

Get connection string and queue

The connection string and queue name are passed to the Main() method as command-line arguments. Main() declares two string variables to hold these values:

static void Main(string[] args)
{
    string ServiceBusConnectionString = "";
    string QueueName = "";

    for (int i = 0; i < args.Length; i++)
    {
        var p = new Program();
        if (args[i] == "-ConnectionString")
        {
            Console.WriteLine($"ConnectionString: {args[i+1]}");
            ServiceBusConnectionString = args[i + 1]; 
        }
        else if(args[i] == "-QueueName")
        {
            Console.WriteLine($"QueueName: {args[i+1]}");
            QueueName = args[i + 1];
        }                
    }

    if (ServiceBusConnectionString != "" && QueueName != "")
        MainAsync(ServiceBusConnectionString, QueueName).GetAwaiter().GetResult();
    else
    {
        Console.WriteLine("Specify -Connectionstring and -QueueName to execute the example.");
        Console.ReadKey();
    }                            
}

The Main() method then starts the asynchronous message loop, MainAsync().

Message loop

The MainAsync() method creates a queue client with the command-line arguments, calls a receiving message handler named RegisterOnMessageHandlerAndReceiveMessages(), and sends the set of messages:

static async Task MainAsync(string ServiceBusConnectionString, string QueueName)
{
    const int numberOfMessages = 10;
    queueClient = new QueueClient(ServiceBusConnectionString, QueueName);

    Console.WriteLine("======================================================");
    Console.WriteLine("Press any key to exit after receiving all the messages.");
    Console.WriteLine("======================================================");

    // Register QueueClient's MessageHandler and receive messages in a loop
    RegisterOnMessageHandlerAndReceiveMessages();

    // Send Messages
    await SendMessagesAsync(numberOfMessages);

    Console.ReadKey();

    await queueClient.CloseAsync();
}

The RegisterOnMessageHandlerAndReceiveMessages() method simply sets a few message handler options, then calls the queue client's RegisterMessageHandler() method, which starts the receiving:

static void RegisterOnMessageHandlerAndReceiveMessages()
{
    // Configure the MessageHandler Options in terms of exception handling, number of concurrent messages to deliver etc.
    var messageHandlerOptions = new MessageHandlerOptions(ExceptionReceivedHandler)
    {
        // Maximum number of Concurrent calls to the callback `ProcessMessagesAsync`, set to 1 for simplicity.
        // Set it according to how many messages the application wants to process in parallel.
        MaxConcurrentCalls = 1,

        // Indicates whether MessagePump should automatically complete the messages after returning from User Callback.
        // False below indicates the Complete will be handled by the User Callback as in `ProcessMessagesAsync` below.
        AutoComplete = false
    };

    // Register the function that will process messages
    queueClient.RegisterMessageHandler(ProcessMessagesAsync, messageHandlerOptions);
} 

Send messages

The message creation and send operations occur in the SendMessagesAsync() method:

static async Task SendMessagesAsync(int numberOfMessagesToSend)
{
    try
    {
        for (var i = 0; i < numberOfMessagesToSend; i++)
        {
            // Create a new message to send to the queue
            string 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 queue
            await queueClient.SendAsync(message);
        }
    }
    catch (Exception exception)
    {
        Console.WriteLine($"{DateTime.Now} :: Exception: {exception.Message}");
    }
}

Process messages

The ProcessMessagesAsync() method acknowledges, processes, and completes the receipt of the messages:

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

    // Complete the message so that it is not received again.
    await queueClient.CompleteAsync(message.SystemProperties.LockToken);
}

Note

You can manage Service Bus resources with Service Bus Explorer. The Service Bus Explorer allows users to connect to a Service Bus namespace and administer messaging entities in an easy manner. The tool provides advanced features like import/export functionality or the ability to test topic, queues, subscriptions, relay services, notification hubs and events hubs.

Next steps

In this article, you created a Service Bus namespace and other resources required to send and receive messages from a queue. To learn more about writing code to send and receive messages, continue to the tutorials in the Send and receive messages section.