Ejercicio: Envío y recepción de mensajes mediante un tema

Completado

Ha decidido usar un tema de Azure Service Bus para distribuir mensajes sobre el rendimiento de ventas en la aplicación de Salesforce. El personal de ventas usará la aplicación en sus dispositivos móviles para enviar mensajes que resumen las cifras de ventas para cada área y período de tiempo. Esos mensajes se distribuyen a los servicios web ubicados en las regiones operativas de la empresa, incluidas Américas y Europa.

Ya ha implementado la infraestructura necesaria en las suscripciones de Azure para el tema. Ahora quiere escribir el código que envía mensajes al tema y el código que recupera mensajes de una suscripción. A continuación, enviará un mensaje a un tema y recuperará el mensaje de una suscripción específica.

Asegúrese de que trabaja en el directorio correcto mediante la ejecución de los comandos siguientes en Azure Cloud Shell:

cd ~/mslearn-connect-services-together/implement-message-workflows-with-service-bus/src/start
code .

Escritura de código para enviar un mensaje a un tema

Para completar el componente que envía mensajes sobre el rendimiento de ventas, siga estos pasos:

  1. En el editor de Azure Cloud Shell, abra performancemessagesender/Program.cs y busque la línea de código siguiente:

    const string ServiceBusConnectionString = "";
    

    Pegue entre comillas la cadena de conexión que guardó en el ejercicio anterior.

  2. Si usó un nombre distinto de salesperformancemessages para el nombre de la cola, actualice el valor de la propiedad TopicName en el código:

    const string TopicName = "salesperformancemessages";
    
  3. Busque el método SendPerformanceMessageAsync(). (Sugerencia: está en la línea 26 o cerca de ella). Dentro de ese método, busque la siguiente línea de código:

    // Create a Service Bus client here
    

    Reemplace esa línea de código por este código:

    // By leveraging "await using", the DisposeAsync method will be called automatically when the client variable goes out of scope.
    // In more realistic scenarios, you would store off a class reference to the client (rather than to a local variable) so that it can be used throughout your program.
    await using var client = new ServiceBusClient(ServiceBusConnectionString);
    
  4. En el método SendPerformanceMessageAsync(), busque la siguiente línea de código:

    // Create a sender here
    

    Reemplace esa línea de código por este código:

    await using ServiceBusSender sender = client.CreateSender(TopicName);
    
  5. En el bloque try...catch, busque la siguiente línea de código:

    // Create and send a message here
    

    Reemplace esa línea de código por este código:

    string messageBody = "Total sales for Brazil in August: $13m.";
    var message = new ServiceBusMessage(messageBody);
    
  6. Para mostrar el mensaje en la consola, inserte el código siguiente en la línea posterior:

    Console.WriteLine($"Sending message: {messageBody}");
    
  7. Para enviar el mensaje al tema, inserte el código siguiente en la línea posterior:

    await sender.SendMessageAsync(message);
    
  8. Compruebe que el código final es similar al ejemplo siguiente:

    using System;
    using System.Threading.Tasks;
    using Azure.Messaging.ServiceBus;
    
    namespace performancemessagesender
    {
        class Program
        {
            const string ServiceBusConnectionString = "Endpoint=sb://example.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=AbCdEfGhIjKlMnOpQrStUvWxYz==";
            const string TopicName = "salesperformancemessages";
    
            static void Main(string[] args)
            {
                Console.WriteLine("Sending a message to the Sales Performance topic...");
                SendPerformanceMessageAsync().GetAwaiter().GetResult();
                Console.WriteLine("Message was sent successfully.");
            }
    
            static async Task SendPerformanceMessageAsync()
            {
                // By leveraging "await using", the DisposeAsync method will be called automatically once the client variable goes out of scope.
                // In more realistic scenarios, you would store off a class reference to the client (rather than to a local variable) so that it can be used throughout your program.
                await using var client = new ServiceBusClient(ServiceBusConnectionString);
    
                await using ServiceBusSender sender = client.CreateSender(TopicName);
    
                try
                {
                    string messageBody = "Total sales for Brazil in August: $13m.";
                    var message = new ServiceBusMessage(messageBody);
                    Console.WriteLine($"Sending message: {messageBody}");
                    await sender.SendMessageAsync(message);
                }
                catch (Exception exception)
                {
                    Console.WriteLine($"{DateTime.Now} :: Exception: {exception.Message}");
                }
            }
        }
    }
    
  9. Para guardar los cambios, presione Ctrl+S y, después, Ctrl+Q para cerrar el editor.

Enviar un mensaje al tema

  1. Para ejecutar el componente que envía un mensaje sobre una venta, ejecute el comando siguiente en Cloud Shell:

    dotnet run --project performancemessagesender
    
  2. A medida que se ejecuta el programa, observe las notificaciones en Cloud Shell que indican que se está enviando un mensaje. Cada vez que se ejecuta la aplicación, se agrega otro mensaje al tema y hay una copia disponible para cada suscripción.

    Sending a message to the Sales Performance topic...
    Sending message: Total sales for Brazil in August: $13m.
    Message was sent successfully.
    

Comprobación del número de mensajes antes de recuperar los mensajes de una suscripción

Cuando vea Message was sent successfully, ejecute el siguiente comando para ver cuántos mensajes hay en la suscripción Americas. Recuerde reemplazar <espacio_de_nombres> por el espacio de nombres de Service Bus.

az servicebus topic subscription show \
    --resource-group <rgn>[sandbox resource group name]</rgn> \
    --topic-name salesperformancemessages \
    --name Americas \
    --query messageCount \
    --namespace-name <namespace-name>

Si reemplaza Americas por EuropeAndAsia y vuelve a ejecutar el comando, verá que ambas suscripciones tienen el mismo número de mensajes.

Escritura de código para recuperar un mensaje del tema para una suscripción

Para crear el componente que recupera mensajes sobre el rendimiento de ventas, complete estos pasos:

  1. Ejecute code . para iniciar el editor.

  2. En el editor, abra performancemessagereceiver/Program.cs y busque la línea de código siguiente:

    const string ServiceBusConnectionString = "";
    

    Pegue entre comillas la cadena de conexión que guardó en el ejercicio anterior.

  3. Para crear un cliente de Service Bus, busque el método MainAsync(). Dentro del método, busque la siguiente línea de código:

    // Create a Service Bus client that will authenticate using a connection string
    

    Reemplace esa línea por este código:

    var client = new ServiceBusClient(ServiceBusConnectionString);
    
  4. Para configurar las opciones de control de mensajes, busque la siguiente línea de código:

    // Create the options to use for configuring the processor
    

    Reemplace esa línea por este código:

    var processorOptions = new ServiceBusProcessorOptions
    {
        MaxConcurrentCalls = 1,
        AutoCompleteMessages = false
    };
    
  5. Para crear un procesador, busque la siguiente línea de código:

    // Create a processor that we can use to process the messages
    

    Reemplace esa línea por este código:

    ServiceBusProcessor processor = client.CreateProcessor(TopicName, SubscriptionName, processorOptions);
    
  6. Para configurar el controlador, busque la siguiente línea de código:

    // Configure the message and error handler to use
    

    Reemplace esa línea por este código:

    processor.ProcessMessageAsync += MessageHandler;
    processor.ProcessErrorAsync += ErrorHandler;
    
  7. Para empezar a procesar, busque la siguiente línea de código:

    // Start processing
    

    Reemplace esa línea por este código:

    await processor.StartProcessingAsync();
    
  8. Busque la línea de código siguiente:

    // Since we didn't use the "await using" syntax here, we need to explicitly dispose the processor and client    
    

    Reemplace la línea por este código:

    await processor.DisposeAsync();
    await client.DisposeAsync();    
    
  9. Para mostrar los mensajes entrantes en la consola, busque el método MessageHandler(). Ha registrado este método para controlar los mensajes entrantes.

    Reemplace todo el código dentro de ese método por el código siguiente:

    Console.WriteLine($"Received message: SequenceNumber:{args.Message.SequenceNumber} Body:{args.Message.Body}");
    
  10. Para quitar el mensaje recibido de la suscripción, agregue el código siguiente en la línea siguiente:

    await args.CompleteMessageAsync(args.Message);
    
  11. Compruebe que el código final es similar al ejemplo siguiente:

    using System;
    using System.Text;
    using System.Threading;
    using System.Threading.Tasks;
    using Azure.Messaging.ServiceBus;
    
    namespace performancemessagereceiver
    {
        class Program
        {
            const string ServiceBusConnectionString = "Endpoint=sb://alexgeddyneil.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=LIWIyxs8baqQ0bRf5zJLef6OTfrv0kBEDxFM/ML37Zs=";
            const string TopicName = "salesperformancemessages";
            const string SubscriptionName = "Americas";
    
            static void Main(string[] args)
            {
                MainAsync().GetAwaiter().GetResult();
            }
    
            static async Task MainAsync()
            {
                var client = new ServiceBusClient(ServiceBusConnectionString);
    
                Console.WriteLine("======================================================");
                Console.WriteLine("Press ENTER key to exit after receiving all the messages.");
                Console.WriteLine("======================================================");
    
                var processorOptions = new ServiceBusProcessorOptions
                {
                    MaxConcurrentCalls = 1,
                    AutoCompleteMessages = false
                };
    
                ServiceBusProcessor processor = client.CreateProcessor(TopicName, SubscriptionName, processorOptions);
    
                processor.ProcessMessageAsync += MessageHandler;
                processor.ProcessErrorAsync += ErrorHandler;
    
                await processor.StartProcessingAsync();
    
                Console.Read();
    
                await processor.DisposeAsync();
                await client.DisposeAsync();
            }
    
            static async Task MessageHandler(ProcessMessageEventArgs args)
            {
                Console.WriteLine($"Received message: SequenceNumber:{args.Message.SequenceNumber} Body:{args.Message.Body}");
                await args.CompleteMessageAsync(args.Message);
            }
    
            static Task ErrorHandler(ProcessErrorEventArgs args)
            {
                Console.WriteLine($"Message handler encountered an exception {args.Exception}.");
                Console.WriteLine("Exception context for troubleshooting:");
                Console.WriteLine($"- Endpoint: {args.FullyQualifiedNamespace}");
                Console.WriteLine($"- Entity Path: {args.EntityPath}");
                Console.WriteLine($"- Executing Action: {args.ErrorSource}");
                return Task.CompletedTask;
            }
        }
    }
    
  12. Para guardar los cambios, presione Ctrl+S y, después, Ctrl+Q para cerrar el editor.

Recuperación de un mensaje de un tema para una suscripción

  1. Para ejecutar el componente que recupera un mensaje sobre el rendimiento de ventas para una suscripción, ejecute el comando siguiente:

    dotnet run --project performancemessagereceiver
    

    Verá un resultado similar al del siguiente ejemplo:

    Received message: SequenceNumber:1 Body:Total sales for Brazil in August: $13m.
    
  2. Cuando el programa haya devuelto notificaciones de recepción de mensajes, presione ENTRAR para detener la aplicación.

Comprobación del número de mensajes después de recuperar un mensaje para una suscripción

Ejecute el siguiente comando para confirmar que no hay ningún mensaje restante en la suscripción de Americas. Asegúrese de reemplazar <espacio_de_nombres> por el espacio de nombres de Service Bus.

az servicebus topic subscription show \
     --resource-group <rgn>[sandbox resource group name]</rgn> \
     --topic-name salesperformancemessages \
     --name Americas \
     --query messageCount \
     --namespace-name <namespace-name> 

Si reemplaza Americas por EuropeAndAsia en este código para ver el número de mensajes actual de la suscripción de EuropeAndAsia, verá que número de mensajes es 1. En el código anterior, solo se estableció Americas para recuperar mensajes del tema, por lo que ese mensaje todavía está esperando a EuropeAndAsia para recuperarlo.