Service Bus 큐 시작Get started with Service Bus queues

이 자습서에서는 Service Bus 큐에 메시지를 보내고 메시지를 수신 하는 .NET Core 콘솔 응용 프로그램을 만듭니다.In this tutorial, you create .NET Core console applications to send messages to and receive messages from a Service Bus queue.

선행 조건Prerequisites

큐에 메시지 보내기Send messages to the queue

큐에 메시지를 보내려면 Visual Studio를 사용하여 C# 콘솔 애플리케이션을 작성합니다.To send messages to the queue, write a C# console application using Visual Studio.

콘솔 애플리케이션 만들기Create a console application

Visual Studio를 시작 하 고에 대 한 C#새 콘솔 앱 (.net Core) 프로젝트를 만듭니다.Launch Visual Studio and create a new Console App (.NET Core) project for C#. 이 예제에서는 CoreSenderApp앱의 이름을로 합니다.This example names the app CoreSenderApp.

Service Bus NuGet 패키지 추가Add the Service Bus NuGet package

  1. 마우스 오른쪽 단추로 새롭게 만든 프로젝트를 클릭하고 NuGet 패키지 관리를 선택합니다.Right-click the newly created project and select Manage NuGet Packages.

  2. 찾아보기를 선택합니다.Select Browse. ServiceBus 를 검색 하 고 선택 합니다.Search for and select Microsoft.Azure.ServiceBus.

  3. 설치 를 선택 하 여 설치를 완료 한 다음 NuGet 패키지 관리자를 닫습니다.Select Install to complete the installation, then close the NuGet Package Manager.

    NuGet 패키지 선택

코드를 작성하여 큐에 메시지 보내기Write code to send messages to the queue

  1. Program.cs에서 네임 스페이스 정의의 맨 위에 클래스 선언 앞에 다음 using 문을 추가 합니다.In Program.cs, add the following using statements at the top of the namespace definition, before the class declaration:

    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using Microsoft.Azure.ServiceBus;
    
  2. Program 클래스에서 다음 변수를 선언 합니다.In the Program class, declare the following variables:

    const string ServiceBusConnectionString = "<your_connection_string>";
    const string QueueName = "<your_queue_name>";
    static IQueueClient queueClient;
    

    네임 스페이스에 대 한 연결 문자열을 ServiceBusConnectionString 변수로 입력 합니다.Enter your connection string for the namespace as the ServiceBusConnectionString variable. 큐 이름을 입력 합니다.Enter your queue name.

  3. Main()이라는 기본 내용을 다음 코드줄로 바꿉니다.Replace the default contents of Main() with the following line of code:

    MainAsync().GetAwaiter().GetResult();
    
  4. Main()의 바로 뒤에 메시지 전송 메서드를 호출하는 다음 비동기 MainAsync() 메서드를 추가합니다.Directly after Main(), add the following asynchronous MainAsync() method that calls the send messages method:

    static async Task MainAsync()
    {
        const int numberOfMessages = 10;
        queueClient = new QueueClient(ServiceBusConnectionString, QueueName);
    
        Console.WriteLine("======================================================");
        Console.WriteLine("Press ENTER key to exit after sending all the messages.");
        Console.WriteLine("======================================================");
    
        // Send messages.
        await SendMessagesAsync(numberOfMessages);
    
        Console.ReadKey();
    
        await queueClient.CloseAsync();
    }
    
  5. MainAsync() 메서드 바로 다음에 numberOfMessagesToSend으로 지정 된 메시지 수를 전송 하는 작업을 수행 하는 다음 SendMessagesAsync() 메서드 (현재 10으로 설정 됨)를 추가 합니다.Directly after the MainAsync() method, add the following SendMessagesAsync() method that does the work of sending the number of messages specified by numberOfMessagesToSend (currently set to 10):

    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}");
        }
    }
    

Program.cs 파일은 다음과 같이 표시 됩니다.Here is what your Program.cs file should look like.

namespace CoreSenderApp
{
    using System;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using Microsoft.Azure.ServiceBus;

    class Program
    {
        // Connection String for the namespace can be obtained from the Azure portal under the 
        // 'Shared Access policies' section.
        const string ServiceBusConnectionString = "<your_connection_string>";
        const string QueueName = "<your_queue_name>";
        static IQueueClient queueClient;

        static void Main(string[] args)
        {
            MainAsync().GetAwaiter().GetResult();
        }

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

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

            // Send Messages
            await SendMessagesAsync(numberOfMessages);

            Console.ReadKey();

            await queueClient.CloseAsync();
        }

        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}");
            }
        }
    }
}

프로그램을 실행 하 고 Azure Portal 확인 합니다.Run the program and check the Azure portal.

Queue Essentials를 표시 하려면 네임 스페이스 개요 창에서 큐의 이름을 선택 합니다.Select the name of your queue in the namespace Overview window to display queue Essentials.

개수 및 크기와 함께 수신 된 메시지

이제 큐에 대 한 활성 메시지 수 값이 10입니다.The Active message count value for the queue is now 10. 메시지를 검색 하지 않고이 발신자 앱을 실행할 때마다이 값이 10 씩 늘어납니다.Each time you run this sender app without retrieving the messages, this value increases by 10.

앱이 큐에 메시지를 추가할 때마다 큐의 현재 크기는 Essentials현재 값을 증가 시킵니다.The current size of the queue increments the CURRENT value in Essentials each time the app adds messages to the queue.

다음 섹션에서는 이러한 메시지를 검색 하는 방법을 설명 합니다.The next section describes how to retrieve these messages.

큐에서 메시지 받기Receive messages from the queue

보낸 메시지를 수신 하려면 다른 콘솔 앱 (.Net Core) 응용 프로그램을 만듭니다.To receive the messages you sent, create another Console App (.NET Core) application. 보낸 사람 응용 프로그램의 경우와 마찬가지로 ServiceBus NuGet 패키지를 설치 합니다.Install the Microsoft.Azure.ServiceBus NuGet package, as you did for the sender application.

코드를 작성하여 큐에서 메시지 받기Write code to receive messages from the queue

  1. Program.cs에서 네임 스페이스 정의의 맨 위에 클래스 선언 앞에 다음 using 문을 추가 합니다.In Program.cs, add the following using statements at the top of the namespace definition, before the class declaration:

    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using Microsoft.Azure.ServiceBus;
    
  2. Program 클래스에서 다음 변수를 선언 합니다.In the Program class, declare the following variables:

    const string ServiceBusConnectionString = "<your_connection_string>";
    const string QueueName = "<your_queue_name>";
    static IQueueClient queueClient;
    

    네임 스페이스에 대 한 연결 문자열을 ServiceBusConnectionString 변수로 입력 합니다.Enter your connection string for the namespace as the ServiceBusConnectionString variable. 큐 이름을 입력 합니다.Enter your queue name.

  3. Main()이라는 기본 내용을 다음 코드줄로 바꿉니다.Replace the default contents of Main() with the following line of code:

    MainAsync().GetAwaiter().GetResult();
    
  4. Main()의 바로 뒤에 MainAsync() 메서드를 호출하는 다음 비동기 RegisterOnMessageHandlerAndReceiveMessages() 메서드를 추가합니다.Directly after Main(), add the following asynchronous MainAsync() method that calls the RegisterOnMessageHandlerAndReceiveMessages() method:

    static async Task MainAsync()
    {
        queueClient = new QueueClient(ServiceBusConnectionString, QueueName);
    
        Console.WriteLine("======================================================");
        Console.WriteLine("Press ENTER key to exit after receiving all the messages.");
        Console.WriteLine("======================================================");
    
        // Register the queue message handler and receive messages in a loop
        RegisterOnMessageHandlerAndReceiveMessages();
    
        Console.ReadKey();
    
        await queueClient.CloseAsync();
    }
    
  5. MainAsync() 메서드 바로 뒤에 다음 메서드를 추가 합니다 .이 메서드는 메시지 처리기를 등록 하 고 발신자 응용 프로그램에서 보낸 메시지를 받습니다.Directly after the MainAsync() method, add the following method, which registers the message handler and receives the messages sent by the sender application:

    static void RegisterOnMessageHandlerAndReceiveMessages()
    {
        // Configure the message handler 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 the message pump should automatically complete the messages after returning from user callback.
            // False below indicates the complete operation is handled by the user callback as in ProcessMessagesAsync().
            AutoComplete = false
        };
    
        // Register the function that processes messages.
        queueClient.RegisterMessageHandler(ProcessMessagesAsync, messageHandlerOptions);
    }
    
  6. 이전 메서드의 바로 뒤에 수신된 메시지를 처리하는 다음 ProcessMessagesAsync() 메서드를 추가합니다.Directly after the previous method, add the following ProcessMessagesAsync() method to process the received 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.
        // This can be done only if the queue Client is created in ReceiveMode.PeekLock mode (which is the default).
        await queueClient.CompleteAsync(message.SystemProperties.LockToken);
    
        // Note: Use the cancellationToken passed as necessary to determine if the queueClient has already been closed.
        // If queueClient has already been closed, you can choose to not call CompleteAsync() or AbandonAsync() etc.
        // to avoid unnecessary exceptions.
    }
    
  7. 마지막으로 발생할 수 있는 모든 예외를 처리하는 다음 메서드를 추가합니다.Finally, add the following method to handle any exceptions that might occur:

    // Use this handler to examine the exceptions received on the message pump.
    static Task ExceptionReceivedHandler(ExceptionReceivedEventArgs exceptionReceivedEventArgs)
    {
        Console.WriteLine($"Message handler encountered an exception {exceptionReceivedEventArgs.Exception}.");
        var context = exceptionReceivedEventArgs.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;
    }
    

Program.cs 파일은 다음과 같습니다.Here is what your Program.cs file should look like:

namespace CoreReceiverApp
{
    using System;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using Microsoft.Azure.ServiceBus;

    class Program
    {
        // Connection String for the namespace can be obtained from the Azure portal under the 
        // 'Shared Access policies' section.
        const string ServiceBusConnectionString = "<your_connection_string>";
        const string QueueName = "<your_queue_name>";
        static IQueueClient queueClient;

        static void Main(string[] args)
        {
            MainAsync().GetAwaiter().GetResult();
        }

        static async Task MainAsync()
        {
            queueClient = new QueueClient(ServiceBusConnectionString, QueueName);

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

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

            await queueClient.CloseAsync();
        }

        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);
        }

        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.
            // This can be done only if the queueClient is created in ReceiveMode.PeekLock mode (which is default).
            await queueClient.CompleteAsync(message.SystemProperties.LockToken);

            // Note: Use the cancellationToken passed as necessary to determine if the queueClient has already been closed.
            // If queueClient has already been Closed, you may chose to not call CompleteAsync() or AbandonAsync() etc. calls 
            // to avoid unnecessary exceptions.
        }

        static Task ExceptionReceivedHandler(ExceptionReceivedEventArgs exceptionReceivedEventArgs)
        {
            Console.WriteLine($"Message handler encountered an exception {exceptionReceivedEventArgs.Exception}.");
            var context = exceptionReceivedEventArgs.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;
        }
    }
}

프로그램을 실행하고 포털을 다시 확인합니다.Run the program, and check the portal again. 활성 메시지 수현재 값이 이제 0입니다.The Active message count and CURRENT values are now 0.

메시지를 받은 후 큐

축하합니다!Congratulations! 이제 큐를 만들고, 큐에 메시지 집합을 보내고, 동일한 큐에서 해당 메시지를 수신 했습니다.You've now created a queue, sent a set of messages to that queue, and received those messages from the same queue.

참고

Service Bus 탐색기로 Service Bus 리소스를 관리할 수 있습니다.You can manage Service Bus resources with Service Bus Explorer. 사용자는 Service Bus 탐색기를 사용 하 여 Service Bus 네임 스페이스에 쉽게 연결 하 고 메시징 엔터티를 관리할 수 있습니다.The Service Bus Explorer allows users to easily connect to a Service Bus namespace and administer messaging entities. 이 도구는 가져오기/내보내기 기능 또는 토픽, 큐, 구독, 릴레이 서비스, notification hubs 및 event hubs를 테스트 하는 기능과 같은 고급 기능을 제공 합니다.The tool provides advanced features like import/export functionality or the ability to test topics, queues, subscriptions, relay services, notification hubs, and event hubs.

다음 단계Next steps

Service Bus 메시징의 많은 고급 기능 중 일부를 보여 주는 샘플이 있는 GitHub 리포지토리를 확인합니다.Check out our GitHub repository with samples that demonstrate some of the more advanced features of Service Bus messaging.