Introducción a las colas de Service BusGet started with Service Bus topics

En este tutorial se describen los pasos siguientes:This tutorial covers the following steps:

  1. Escriba una aplicación de consola de .NET Core para enviar un conjunto de mensajes al tema.Write a .NET Core console application to send a set of messages to the topic.
  2. Escriba una aplicación de consola de .NET Core para recibir esos mensajes de la suscripción.Write a .NET Core console application to receive those messages from the subscription.

Requisitos previosPrerequisites

  1. Una suscripción de Azure.An Azure subscription. Para completar este tutorial, deberá tener una cuenta de Azure.To complete this tutorial, you need an Azure account. Puede activar sus beneficios de suscriptor de Visual Studio o MSDN o registrarse para obtener una cuenta gratuita.You can activate your Visual Studio or MSDN subscriber benefits or sign-up for a free account.
  2. Siga los pasos de Inicio rápido: Use Azure Portal para crear un tema de Service Bus y suscripciones al tema para realizar las siguientes tareas:Follow steps in the Quickstart: Use the Azure portal to create a Service Bus topic and subscriptions to the topic to do the following tasks:
    1. Cree un espacio de nombres de Service Bus.Create a Service Bus namespace.
    2. Obtenga la cadena de conexión.Get the connection string.
    3. Cree un tema en el espacio de nombres.Create a topic in the namespace.
    4. Cree una suscripción al tema en el espacio de nombres.Create one subscription to the topic in the namespace.
  3. Visual Studio 2017 Update 3 (versión 15.3, 26730.01) o posterior.Visual Studio 2017 Update 3 (version 15.3, 26730.01) or later.
  4. NET Core SDK, versión 2.0 o posterior.NET Core SDK, version 2.0 or later.

Envío de mensajes al temaSend messages to the topic

Para enviar mensajes al tema, escriba una aplicación de consola en C# mediante Visual Studio.To send messages to the topic, write a C# console application using Visual Studio.

Creación de una aplicación de consolaCreate a console application

Inicie Visual Studio y cree un nuevo proyecto Aplicación de consola (.NET Core) .Launch Visual Studio and create a new Console App (.NET Core) project.

Agregar el paquete NuGet de Service BusAdd the Service Bus NuGet package

  1. Haga clic con el botón derecho en el proyecto recién creado y seleccione Administrar paquetes NuGet.Right-click the newly created project and select Manage NuGet Packages.

  2. Haga clic en la pestaña Examinar, busque Microsoft.Azure.ServiceBus y seleccione el elemento WindowsAzure.ServiceBus.Click the Browse tab, search for Microsoft.Azure.ServiceBus, and then select the Microsoft.Azure.ServiceBus item. Haga clic en Instalar para completar la instalación y, a continuación, cierre este cuadro de diálogo.Click Install to complete the installation, then close this dialog box.

    Seleccionar un paquete NuGet

Escritura del código para enviar mensajes al temaWrite code to send messages to the topic

  1. En Program.cs, agregue las siguientes instrucciones using en la parte superior de la definición del espacio de nombres, antes de la declaración de clase: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. En la clase Program, declare las variables siguientes.Within the Program class, declare the following variables. Establezca la variable ServiceBusConnectionString en la cadena de conexión que obtuvo al crear el espacio de nombres y establezca TopicName en el nombre que usó cuando creó el tema:Set the ServiceBusConnectionString variable to the connection string that you obtained when creating the namespace, and set TopicName to the name that you used when creating the topic:

    const string ServiceBusConnectionString = "<your_connection_string>";
    const string TopicName = "<your_topic_name>";
    static ITopicClient topicClient;
    
  3. Reemplace el contenido predeterminado de Main() con la siguiente línea de código:Replace the default contents of Main() with the following line of code:

    MainAsync().GetAwaiter().GetResult();
    
  4. Directamente después de Main(), agregue el siguiente método MainAsync() asincrónico que llama al método para enviar mensajes:Directly after Main(), add the following asynchronous MainAsync() method that calls the send messages method:

    static async Task MainAsync()
    {
        const int numberOfMessages = 10;
        topicClient = new TopicClient(ServiceBusConnectionString, TopicName);
    
        Console.WriteLine("======================================================");
        Console.WriteLine("Press ENTER key to exit after sending all the messages.");
        Console.WriteLine("======================================================");
    
        // Send messages.
        await SendMessagesAsync(numberOfMessages);
    
        Console.ReadKey();
    
        await topicClient.CloseAsync();
    }
    
  5. Directamente después del método MainAsync(), agregue el siguiente método SendMessagesAsync() que realiza el trabajo de enviar el número de mensajes especificado por numberOfMessagesToSend (actualmente se establece en 10):Directly after the MainAsync() method, add the following SendMessagesAsync() method that performs 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 topic.
                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 topic.
                await topicClient.SendAsync(message);
            }
        }
        catch (Exception exception)
        {
            Console.WriteLine($"{DateTime.Now} :: Exception: {exception.Message}");
        }
    }
    
  6. Esta es la apariencia que debería tener el archivo Program.cs del emisor.Here is what your sender 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
        {
            const string ServiceBusConnectionString = "<your_connection_string>";
            const string TopicName = "<your_topic_name>";
            static ITopicClient topicClient;
    
            static void Main(string[] args)
            {
                MainAsync().GetAwaiter().GetResult();
            }
    
            static async Task MainAsync()
            {
                const int numberOfMessages = 10;
                topicClient = new TopicClient(ServiceBusConnectionString, TopicName);
    
                Console.WriteLine("======================================================");
                Console.WriteLine("Press ENTER key to exit after sending all the messages.");
                Console.WriteLine("======================================================");
    
                // Send messages.
                await SendMessagesAsync(numberOfMessages);
    
                Console.ReadKey();
    
                await topicClient.CloseAsync();
            }
    
            static async Task SendMessagesAsync(int numberOfMessagesToSend)
            {
                try
                {
                    for (var i = 0; i < numberOfMessagesToSend; i++)
                    {
                        // Create a new message to send to the topic
                        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 topic
                        await topicClient.SendAsync(message);
                    }
                }
                catch (Exception exception)
                {
                    Console.WriteLine($"{DateTime.Now} :: Exception: {exception.Message}");
                }
            }
        }
    }
    
  7. Ejecute el programa y revise Azure Portal: haga clic en el nombre del tema en la ventana Introducción del espacio de nombres.Run the program, and check the Azure portal: click the name of your topic in the namespace Overview window. Se muestra la pantalla Essentials del tema.The topic Essentials screen is displayed. En la suscripción que se enumera cerca de la parte inferior de la ventana, observe que el valor Número de mensajes de la suscripción ahora es 10.In the subscription listed near the bottom of the window, notice that the Message Count value for the subscription is now 10. Cada vez que se ejecuta la aplicación de remitente sin recuperar los mensajes (como se describe en la siguiente sección), este valor aumenta en 10.Each time you run the sender application without retrieving the messages (as described in the next section), this value increases by 10. Tenga en cuenta también que el tamaño actual del tema aumenta el valor de Actual en la ventana Essentials cada vez que la aplicación agrega mensajes al tema.Also note that the current size of the topic increments the Current value in the Essentials window each time the app adds messages to the topic.

    Tamaño del mensaje

Recepción de mensajes de la suscripciónReceive messages from the subscription

Para recibir los mensajes que envió, cree otra aplicación de consola de .NET Core e instale el paquete NuGet Microsoft.Azure.ServiceBus, similar a la aplicación de remitente anterior.To receive the messages you sent, create another .NET Core console application and install the Microsoft.Azure.ServiceBus NuGet package, similar to the previous sender application.

Escritura de código para recibir mensajes de la suscripciónWrite code to receive messages from the subscription

  1. En Program.cs, agregue las siguientes instrucciones using en la parte superior de la definición del espacio de nombres, antes de la declaración de clase: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. En la clase Program, declare las variables siguientes.Within the Program class, declare the following variables. Establezca la variable ServiceBusConnectionString en la cadena de conexión que obtuvo al crear el espacio de nombres, establezca TopicName en el nombre que usó cuando creó el tema y SubscriptionName en el nombre que usó al crear la suscripción al tema:Set the ServiceBusConnectionString variable to the connection string that you obtained when creating the namespace, set TopicName to the name that you used when creating the topic, and set SubscriptionName to the name that you used when creating the subscription to the topic:

    const string ServiceBusConnectionString = "<your_connection_string>";
    const string TopicName = "<your_topic_name>";
    const string SubscriptionName = "<your_subscription_name>";
    static ISubscriptionClient subscriptionClient;
    
  3. Reemplace el contenido predeterminado de Main() con la siguiente línea de código:Replace the default contents of Main() with the following line of code:

    MainAsync().GetAwaiter().GetResult();
    
  4. Directamente después de Main(), agregue el siguiente método MainAsync() asincrónico que llama al método RegisterOnMessageHandlerAndReceiveMessages():Directly after Main(), add the following asynchronous MainAsync() method that calls the RegisterOnMessageHandlerAndReceiveMessages() method:

    static async Task MainAsync()
    {
        subscriptionClient = new SubscriptionClient(ServiceBusConnectionString, TopicName, SubscriptionName);
    
        Console.WriteLine("======================================================");
        Console.WriteLine("Press ENTER key to exit after receiving all the messages.");
        Console.WriteLine("======================================================");
    
        // Register subscription message handler and receive messages in a loop
        RegisterOnMessageHandlerAndReceiveMessages();
    
        Console.ReadKey();
    
        await subscriptionClient.CloseAsync();
    }
    
  5. Directamente después del método MainAsync(), agregue el método siguiente que registra el controlador de mensajes y recibe los mensajes enviados por la aplicación remitente:Directly after the MainAsync() method, add the following method that 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.
        subscriptionClient.RegisterMessageHandler(ProcessMessagesAsync, messageHandlerOptions);
    }
    
  6. Directamente después del método anterior, agregue el siguiente método ProcessMessagesAsync() para procesar los mensajes recibidos: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 subscriptionClient is created in ReceiveMode.PeekLock mode (which is the default).
        await subscriptionClient.CompleteAsync(message.SystemProperties.LockToken);
    
        // Note: Use the cancellationToken passed as necessary to determine if the subscriptionClient has already been closed.
        // If subscriptionClient has already been closed, you can choose to not call CompleteAsync() or AbandonAsync() etc.
        // to avoid unnecessary exceptions.
    }
    
  7. Por último, agregue el siguiente método para controlar las excepciones que pueden producirse: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;
    }    
    
  8. Esta es la apariencia que debería tener el archivo Program.cs del receptor:Here is what your receiver 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
        {
            const string ServiceBusConnectionString = "<your_connection_string>";
            const string TopicName = "<your_topic_name>";
            const string SubscriptionName = "<your_subscription_name>";
            static ISubscriptionClient subscriptionClient;
    
            static void Main(string[] args)
            {
                MainAsync().GetAwaiter().GetResult();
            }
    
            static async Task MainAsync()
            {
                subscriptionClient = new SubscriptionClient(ServiceBusConnectionString, TopicName, SubscriptionName);
    
                Console.WriteLine("======================================================");
                Console.WriteLine("Press ENTER key to exit after receiving all the messages.");
                Console.WriteLine("======================================================");
    
                // Register subscription message handler and receive messages in a loop.
                RegisterOnMessageHandlerAndReceiveMessages();
    
                Console.ReadKey();
    
                await subscriptionClient.CloseAsync();
            }
    
            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 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 processes messages.
                subscriptionClient.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 subscriptionClient is created in ReceiveMode.PeekLock mode (which is the default).
                await subscriptionClient.CompleteAsync(message.SystemProperties.LockToken);
    
                // Note: Use the cancellationToken passed as necessary to determine if the subscriptionClient has already been closed.
                // If subscriptionClient has already been closed, you can choose to not call CompleteAsync() or AbandonAsync() etc.
                // 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;
            }
        }
    }
    
  9. Ejecute el programa y vuelva a comprobar el portal.Run the program, and check the portal again. Tenga en cuenta que los valores de Recuento de mensajes y Actual ahora son 0.Notice that the Message Count and Current values are now 0.

    Longitud del tema

Felicidades.Congratulations! Con la biblioteca estándar. NET, ahora ha creado un tema y una suscripción, y enviado y recibido diez mensajes.Using the .NET Standard library, you have now created a topic and subscription, sent 10 messages, and received those messages.

Nota

Puede administrar los recursos de Service Bus con el Explorador de Service Bus.You can manage Service Bus resources with Service Bus Explorer. El Explorador de Service Bus permite a los usuarios conectarse a un espacio de nombres de Service Bus y administrar las entidades de mensajería de una forma sencilla.The Service Bus Explorer allows users to connect to a Service Bus namespace and administer messaging entities in an easy manner. La herramienta dispone de características avanzadas, como la funcionalidad de importación y exportación o la capacidad de probar el tema, las colas, las suscripciones, los servicios de retransmisión, los centros de notificaciones y los centros de eventos.The tool provides advanced features like import/export functionality or the ability to test topic, queues, subscriptions, relay services, notification hubs and events hubs.

Pasos siguientesNext steps

Consulte nuestro repositorio de GitHub con ejemplos de Service Bus, donde se muestran algunas de las características más avanzadas de la mensajería de Service Bus.Check out the Service Bus GitHub repository with samples that demonstrate some of the more advanced features of Service Bus messaging.