Exercício - Enviar e receber mensagens usando um tópico
Você decidiu usar um tópico do Barramento de Serviço do Azure para distribuir mensagens de desempenho de vendas em seu aplicativo Salesforce. A equipe de vendas usará o aplicativo em seus dispositivos móveis para enviar mensagens que resumem os números de vendas para cada área e período de tempo. Essas mensagens são distribuídas para serviços da Web localizados nas regiões operacionais da empresa, incluindo as Américas e a Europa.
Você já implementou a infraestrutura necessária em suas assinaturas do Azure para o tópico. Agora, você deseja escrever o código que envia mensagens para o tópico e escrever o código que recupera mensagens de uma assinatura. Em seguida, você enviará uma mensagem para um tópico e recuperará a mensagem de uma assinatura específica.
Verifique se você está trabalhando no diretório correto executando os seguintes comandos no Azure Cloud Shell:
cd ~/mslearn-connect-services-together/implement-message-workflows-with-service-bus/src/start
code .
Escrever código para enviar uma mensagem para um tópico
Para concluir o componente que envia mensagens sobre o desempenho de vendas, conclua estas etapas:
No editor do Azure Cloud Shell, abra performancemessagesender/Program.cs e localize a seguinte linha de código:
const string ServiceBusConnectionString = "";
Entre aspas, cole a cadeia de conexão salva no exercício anterior.
Se você usou um nome diferente de salesperformancemessages para o nome da fila, atualize o valor da propriedade no
TopicName
código:const string TopicName = "salesperformancemessages";
Encontre o
SendPerformanceMessageAsync()
método. (Dica: está na linha 26 ou perto dela.) Dentro desse método, localize a seguinte linha de código:// Create a Service Bus client here
Substitua essa linha 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);
Dentro do
SendPerformanceMessageAsync()
método, localize a seguinte linha de código:// Create a sender here
Substitua essa linha de código por este código:
await using ServiceBusSender sender = client.CreateSender(TopicName);
try...catch
No bloco , localize a seguinte linha de código:// Create and send a message here
Substitua essa linha de código por este código:
string messageBody = "Total sales for Brazil in August: $13m."; var message = new ServiceBusMessage(messageBody);
Para exibir a mensagem no console, insira o seguinte código na próxima linha:
Console.WriteLine($"Sending message: {messageBody}");
Para enviar a mensagem para o tópico, insira o seguinte código na próxima linha:
await sender.SendMessageAsync(message);
Verifique se o código final é semelhante ao exemplo a seguir:
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}"); } } } }
Para guardar as alterações, prima Ctrl+S e, em seguida, prima Ctrl+Q para fechar o editor.
Enviar uma mensagem para o tópico
Para executar o componente que envia uma mensagem sobre uma venda, execute o seguinte comando no Cloud Shell:
dotnet run --project performancemessagesender
À medida que o programa é executado, observe as notificações no Cloud Shell que indicam que uma mensagem está sendo enviada. Cada vez que você executa o aplicativo, outra mensagem é adicionada ao tópico e uma cópia fica disponível para cada assinatura.
Sending a message to the Sales Performance topic... Sending message: Total sales for Brazil in August: $13m. Message was sent successfully.
Verifique a contagem de mensagens antes de recuperar mensagens para uma assinatura
Quando vir Message was sent successfully
, execute o seguinte comando para ver quantas mensagens existem na Americas
subscrição. Lembre-se de substituir <namespace-name> pelo namespace do 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>
Se você substituir Americas
EuropeAndAsia
e executar o comando novamente, verá que ambas as assinaturas têm o mesmo número de mensagens.
Escrever código para recuperar uma mensagem de tópico para uma assinatura
Para criar o componente que recupera mensagens sobre o desempenho de vendas, conclua estas etapas:
Execute
code .
para iniciar o editor.No editor, abra performancemessagereceiver/Program.cs e localize a seguinte linha de código:
const string ServiceBusConnectionString = "";
Entre aspas, cole a cadeia de conexão salva no exercício anterior.
Para criar um cliente do Service Bus, localize o
MainAsync()
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 essa linha por este código:
var client = new ServiceBusClient(ServiceBusConnectionString);
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 por este código:
var processorOptions = new ServiceBusProcessorOptions { MaxConcurrentCalls = 1, AutoCompleteMessages = false };
Para criar um processador, localize a seguinte linha de código:
// Create a processor that we can use to process the messages
Substitua essa linha por este código:
ServiceBusProcessor processor = client.CreateProcessor(TopicName, SubscriptionName, processorOptions);
Para configurar o manipulador, localize a seguinte linha de código:
// Configure the message and error handler to use
Substitua essa linha por este código:
processor.ProcessMessageAsync += MessageHandler; processor.ProcessErrorAsync += ErrorHandler;
Para iniciar o processamento, localize a seguinte linha de código:
// Start processing
Substitua essa linha por este código:
await processor.StartProcessingAsync();
Procure a seguinte linha de código:
// Since we didn't use the "await using" syntax here, we need to explicitly dispose the processor and client
Substitua a linha por este código:
await processor.DisposeAsync(); await client.DisposeAsync();
Para exibir mensagens de entrada no console, localize o
MessageHandler()
método. Você registrou esse método para lidar com mensagens recebidas.Substitua todo o código dentro desse método com o seguinte código:
Console.WriteLine($"Received message: SequenceNumber:{args.Message.SequenceNumber} Body:{args.Message.Body}");
Para remover a mensagem recebida da subscrição, na linha seguinte, adicione este código:
await args.CompleteMessageAsync(args.Message);
Verifique se o código final é semelhante ao exemplo a seguir:
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; } } }
Para guardar as alterações, prima Ctrl+S e, em seguida, prima Ctrl+Q para fechar o editor.
Recuperar uma mensagem de tópico para uma assinatura
Para executar o componente que recupera uma mensagem sobre o desempenho de vendas de uma assinatura, execute o seguinte comando:
dotnet run --project performancemessagereceiver
Irá ver um resultado semelhante ao do exemplo abaixo:
Received message: SequenceNumber:1 Body:Total sales for Brazil in August: $13m.
Quando o programa retornar notificações de que está recebendo mensagens, pressione Enter para parar o aplicativo.
Verificar a contagem de mensagens depois de recuperar uma mensagem para uma subscrição
Execute o seguinte comando para confirmar que não há mensagens restantes na Americas
assinatura. Certifique-se de substituir <namespace-name> pelo namespace do 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>
Se você substituir Americas
por EuropeAndAsia
neste código para ver a contagem de mensagens atual para a assinatura, verá que a EuropeAndAsia
contagem de mensagens é 1
. No código anterior, apenas Americas
foi definido para recuperar mensagens de tópico, de modo que a mensagem ainda está esperando para EuropeAndAsia
recuperá-lo.