Exercício - Enviar e receber mensagens usando uma fila

Concluído

Você optou por usar uma fila do Barramento de Serviço para lidar com mensagens sobre vendas individuais entre o aplicativo móvel, que sua equipe de vendas usa, e o serviço Web hospedado no Azure, que armazena detalhes sobre cada venda em uma instância do Banco de Dados SQL do Azure.

No exercício anterior, você implementou os objetos necessários em sua assinatura do Azure. Agora, vai escrever o código que envia mensagens para essa fila e obtém mensagens.

Nesta unidade, você cria dois aplicativos de console: um aplicativo coloca mensagens em uma fila do Service Bus e um aplicativo recupera mensagens de uma fila do Service Bus. As aplicações fazem parte de uma única solução .NET Core.

Clonar e abrir a aplicação de arranque

Nota

Para simplificar, as tarefas a seguir instruem você a codificar a cadeia de conexão no arquivo Program.cs de ambos os aplicativos de console. Em uma aplicação de produção, deverás usar a autenticação de controlo de acesso baseada em funções suportada pelo Service Bus da Azure.

  1. Inicie o GitBash no seu computador.

  2. Execute o seguinte comando para clonar a solução de projeto Git:

    cd ~
    git clone https://github.com/MicrosoftDocs/mslearn-connect-services-together.git
    
  3. Inicie o VS Code no seu computador.

  4. Selecione File ->Open Folder ...e, em seguida, selecione a pasta: C:\Program Files\Git\learn-pr\learn-pr\azure\implement-message-workflows-with-service-bus (assumindo que C:\Program Files\Git é a pasta Git). Você deve ver as subpastas final e início. Você trabalha com código no iniciar pasta para escrever código para enviar e receber mensagens. A pasta final contém o código completo.

Escrever código para enviar uma mensagem para uma fila

  1. Na janela "Code Explorer" à esquerda, expanda privatemessagesender.

  2. Abra o Program.cse localize a seguinte linha de código:

    const string ServiceBusConnectionString = "";
    

    Cole a cadeia de ligação entre as aspas.

  3. Se usou um nome diferente de salesmessages para o nome da fila, atualize o valor da propriedade QueueName no código:

    const string QueueName = "salesmessages";
    
  4. Para concluir o componente que envia mensagens sobre vendas, você deve adicionar um await operador para suspender a avaliação do método assíncrono até que a operação assíncrona seja concluída. Encontre o SendSalesMessageAsync() método. Dentro desse método, localize a seguinte linha de código:

    // Create a Service Bus client here
    

    Substitua essa linha de código pelo seguinte código:

    // 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 want to store off a class reference to the client (rather than a local variable) so that it can be used throughout your program.
    
    await using var client = new ServiceBusClient(ServiceBusConnectionString);
    
  5. Dentro do SendSalesMessageAsync() método, localize a seguinte linha de código:

    // Create a sender here
    

    Substitua esse comentário pelo seguinte código:

    await using ServiceBusSender sender = client.CreateSender(QueueName);
    
  6. Dentro do try...catch bloco , localize a seguinte linha de código:

    // Create and send a message here
    

    Substitua essa linha de código pelas seguintes linhas de código:

    string messageBody = $"$10,000 order for bicycle parts from retailer Adventure Works.";
    var message = new ServiceBusMessage(messageBody);
    
  7. Insira o seguinte código em uma nova linha diretamente abaixo do que você acabou de adicionar para exibir a mensagem no console:

    Console.WriteLine($"Sending message: {messageBody}");
    
  8. Insira o seguinte código na próxima linha:

    await sender.SendMessageAsync(message);
    
  9. Para descartar objetos de remetente e cliente, perto do final do arquivo, localize o seguinte comentário:

    // Close the connection to the sender here
    

    Substitua a linha pelo código seguinte:

    finally
    {
        // Calling DisposeAsync on client types is required to ensure that network
        // resources and other unmanaged objects are properly cleaned up.
        await sender.DisposeAsync();
        await client.DisposeAsync();
    }
    
  10. Verifique se o código final para Program.cs é semelhante ao exemplo a seguir:

    using System;
    using System.Text;
    using System.Threading.Tasks;
    using Azure.Messaging.ServiceBus;
    
    namespace privatemessagesender
    {
        class Program
        {
            const string ServiceBusConnectionString = "Endpoint=sb://example.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=xxxxxx";
            const string QueueName = "salesmessages";
    
            static void Main(string[] args)
            {
                Console.WriteLine("Sending a message to the Sales Messages queue...");
                SendSalesMessageAsync().GetAwaiter().GetResult();
                Console.WriteLine("Message was sent successfully.");
            }
    
            static async Task SendSalesMessageAsync()
            {
                await using var client = new ServiceBusClient(ServiceBusConnectionString);
    
                await using ServiceBusSender sender = client.CreateSender(QueueName);
                try
                {
                    string messageBody = $"$10,000 order for bicycle parts from retailer Adventure Works.";
                    var message = new ServiceBusMessage(messageBody);
                    Console.WriteLine($"Sending message: {messageBody}");
                    await sender.SendMessageAsync(message);
                }
                catch (Exception exception)
                {
                    Console.WriteLine($"{DateTime.Now} :: Exception: {exception.Message}");
                }
                finally
                {
                    // Calling DisposeAsync on client types is required to ensure that network
                    // resources and other unmanaged objects are properly cleaned up.
                    await sender.DisposeAsync();
                    await client.DisposeAsync();
                }
            }
        }
    }
    
  11. Para salvar as alterações, selecione Arquivo ->Salvar no menu ou digite Ctrl+S.

Enviar uma mensagem para a fila

  1. No Explorador de Códigos, clique com o botão direito do rato em privatemessagesendere, em seguida, selecione Abrir no Terminal Integrado.

  2. No painel do terminal, no prompt de comando, confirme se está na pasta privatemessagesender e depois digite o seguinte comando: dotnet build.

  3. Agora, execute o aplicativo executando o seguinte comando: dotnet run. À medida que o programa é executado, as mensagens são impressas no console indicando que o aplicativo está enviando uma mensagem:

    Sending a message to the Sales Messages queue...
    Sending message: $10,000 order for bicycle parts from retailer Adventure Works.
    Message was sent successfully.    ```
    
  4. Quando o aplicativo estiver concluído, execute o seguinte comando, substituindo <namespace-name> pelo nome do namespace do Service Bus. Este comando retorna o número de mensagens que estão na fila.

    az servicebus queue show \
        --resource-group "<rgn>[sandbox resource group name]</rgn>" \
        --name salesmessages \
        --query messageCount \
        --namespace-name <namespace-name>
    

Escrever código para receber mensagens da fila

  1. Na página Explorador de Código, expanda privatemessagereceiver.

  2. Abra Program.cse localize a seguinte linha de código:

    const string ServiceBusConnectionString = "";
    

    Entre aspas, cole a cadeia de conexão salva anteriormente.

  3. Encontre o ReceiveSalesMessageAsync() método. Dentro desse método, localize a seguinte linha de código:

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

    Substitua a linha pelo código seguinte:

    var client = new ServiceBusClient(ServiceBusConnectionString);
    
  4. Para configurar as opções de tratamento de mensagens, localize a seguinte linha de código:

    // Create the options to use for configuring the processor
    

    Substitua essa linha pelas seguintes linhas de código:

    var processorOptions = new ServiceBusProcessorOptions
    {
        MaxConcurrentCalls = 1,
        AutoCompleteMessages = false
    };
    
  5. Para criar um processador, localize a seguinte linha de código:

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

    Substitua a linha pelo código seguinte:

    await using ServiceBusProcessor processor = client.CreateProcessor(QueueName, processorOptions);
    
  6. Para configurar os manipuladores, localize a seguinte linha de código:

    // Configure the message and error handler to use
    

    Substitua a linha pelo código seguinte:

    processor.ProcessMessageAsync += MessageHandler;
    processor.ProcessErrorAsync += ErrorHandler;
    
  7. Para iniciar o processamento, localize a seguinte linha de código:

    // Start processing
    

    Substitua a linha pelo código seguinte:

    await processor.StartProcessingAsync();
    
  8. Para fechar a conexão com o Service Bus, localize a seguinte linha de código:

    // Close the processor here
    

    Substitua a linha pelo código seguinte:

    await processor.CloseAsync();
    
  9. Revise o código no MessageHandler método:

    // handle received messages
    static async Task MessageHandler(ProcessMessageEventArgs args)
    {
        // extract the message
        string body = args.Message.Body.ToString();
    
        // print the message
        Console.WriteLine($"Received: {body}");
    
        // complete the message so that message is deleted from the queue. 
        await args.CompleteMessageAsync(args.Message);
    }
    
  10. Revise o código no ErrorHandler método:

    // handle any errors when receiving messages
    static Task ErrorHandler(ProcessErrorEventArgs args)
    {
        // print the exception message
        Console.WriteLine(args.Exception.ToString());
        return Task.CompletedTask;
    }    
    
  11. Verifique se o código final para privatemessagereceiver/Program.cs é semelhante ao exemplo a seguir:

    using System;
    using System.Text;
    using System.Threading.Tasks;
    using Azure.Messaging.ServiceBus;
    
    namespace privatemessagereceiver
    {
        class Program
        {
    
            const string ServiceBusConnectionString = "Endpoint=sb://<examplenamespace.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
            const string QueueName = "salesmessages";
    
            static void Main(string[] args)
            {
    
                ReceiveSalesMessageAsync().GetAwaiter().GetResult();
    
            }
    
            static async Task ReceiveSalesMessageAsync()
            {
    
                Console.WriteLine("======================================================");
                Console.WriteLine("Press ENTER key to exit after receiving all the messages.");
                Console.WriteLine("======================================================");
    
    
                var client = new ServiceBusClient(ServiceBusConnectionString);
    
                var processorOptions = new ServiceBusProcessorOptions
                {
                    MaxConcurrentCalls = 1,
                    AutoCompleteMessages = false
                };
    
                await using ServiceBusProcessor processor = client.CreateProcessor(QueueName, processorOptions);
    
                processor.ProcessMessageAsync += MessageHandler;
                processor.ProcessErrorAsync += ErrorHandler;
    
    
                await processor.StartProcessingAsync();
    
                Console.Read();
    
                await processor.CloseAsync();
    
            }
    
            // handle received messages
            static async Task MessageHandler(ProcessMessageEventArgs args)
            {
                string body = args.Message.Body.ToString();
                Console.WriteLine($"Received: {body}");
    
                // complete the message. messages is deleted from the queue. 
                await args.CompleteMessageAsync(args.Message);
            }
    
            // handle any errors when receiving messages
            static Task ErrorHandler(ProcessErrorEventArgs args)
            {
                Console.WriteLine(args.Exception.ToString());
                return Task.CompletedTask;
            }
        }
    }
    
    
  12. Para guardar as alterações, selecione Ficheiro ->Guardar no menu ou, introduza Ctrl+S.

Receber uma mensagem da fila

  1. No Explorador de Códigos, clique com o botão direito do rato em privatemessagereceivere, em seguida, selecione Abrir no Terminal Integrado.

  2. No painel do terminal, no prompt de comando, confirme se está na pasta privatemessagereceiver e, em seguida, digite o seguinte comando: dotnet build.

  3. Agora, execute o aplicativo executando o seguinte comando: dotnet run.

    ======================================================
    Press ENTER key to exit after receiving all the messages.
    ======================================================
    Received: $10,000 order for bicycle parts from retailer Adventure Works.
    
  4. Quando tu vires que as mensagens foram recebidas no Cloud Shell, ENTER para parar a aplicação.

Verifique a contagem de mensagens

Execute o código a seguir para confirmar que todas as mensagens foram removidas da fila, lembrando-se de substituir <namespace-name> pelo namespace do Service Bus.

az servicebus queue show \
    --resource-group "<rgn>[sandbox resource group name]</rgn>" \
    --name salesmessages \
    --query messageCount \
    --namespace-name <namespace-name>

A saída é 0 se todas as mensagens tiverem sido removidas.

Você escreveu um código que envia uma mensagem sobre vendas individuais para uma fila do Service Bus. No aplicativo distribuído salesforce, você deve escrever esse código no aplicativo móvel que o pessoal de vendas usa nos dispositivos.

Você também escreveu código que recebe uma mensagem da fila do Service Bus. No aplicativo distribuído salesforce, você deve escrever esse código no serviço Web que é executado no Azure e processa as mensagens recebidas.