Escrever código para enviar e receber mensagens usando um tópico

Concluído

Em um aplicativo distribuído, algumas mensagens precisam ser enviadas a um componente de único destinatário. Outras mensagens precisam chegar a mais de um destino.

Considere o que acontece quando um usuário cancela um pedido de uma bicicleta. Cancelar um pedido é um pouco diferente de fazer um pedido inicial. Quando um pedido é feito, o fluxo de trabalho aguarda até que o processamento do pagamento do pedido seja liberado antes de enviar o pedido para a vitrine Web local. Na operação de cancelamento, você notificará a vitrine Web e o processador de pagamento ao mesmo tempo. Essa abordagem minimiza as chances de desperdiçar o tempo do entregador.

Para permitir que vários componentes recebam a mesma mensagem, você usará um tópico do Barramento de Serviços do Azure. Em seguida, você examinará o processo e as considerações ao escrever o código.

Código com tópicos vs. código com filas

Se você deseja que todas as mensagens enviadas sejam entregues a todos os componentes da assinatura, utilize tópicos. Escrever código que usa tópicos é uma maneira de substituir as filas. Você usará o mesmo pacote Azure.Messaging.ServiceBus pacote NuGet, configurar cadeias de caracteres de conexão e usar padrões de programação assíncrona.

Você também usará a mesma classe ServiceBusClient e classes ServiceBusSender para enviar mensagens, e a classe ServiceBusProcessor para receber mensagens.

Definir filtros nas assinaturas

Para que mensagens específicas enviadas ao tópico sejam entregues a uma assinatura específica, você pode colocar um ou mais filtros na assinatura do tópico. No aplicativo de bicicleta, por exemplo, nossas vitrines Web estão executando aplicativos UWP (Plataforma Universal do Windows). Cada loja pode assinar o tópico OrderCancellation e filtrar para seu próprio StoreId. Você economiza largura de banda da Internet porque não está enviando mensagens desnecessárias para várias lojas. Enquanto isso, o componente de processamento de pagamento assina em todas as mensagens OrderCancellation.

Os filtros podem ser de um dos três tipos:

  • Filtros boolianos: O TrueFilter garante que todas as mensagens enviadas ao tópico sejam entregues à assinatura atual. O FalseFilter garante que nenhuma das mensagens seja entregue para a assinatura atual. (Isso efetivamente bloqueia ou desativa a assinatura.)
  • Filtros SQL: Um filtro SQL especifica uma condição usando a mesma sintaxe de uma cláusula WHERE em uma consulta SQL. Somente as mensagens que retornam True quando avaliadas em relação a esse filtro são entregues aos assinantes.
  • Filtros de correlação: Um filtro de correlação mantém um conjunto de condições que são correspondidas em relação às propriedades de cada mensagem. Se a propriedade no filtro e a propriedade na mensagem tiverem o mesmo valor, isso será considerado uma correspondência.

Em seu filtro StoreId, você pode usar um filtro SQL. Os filtros SQL são os mais flexíveis, mas também são os mais caros computacionalmente, o que pode diminuir a taxa de transferência do Barramento de Serviço. Alternativamente, escolha um filtro de correlação.

Para enviar uma mensagem a um tópico

Para enviar uma mensagem a um tópico, realize as seguintes etapas.

Em qualquer componente de envio ou recebimento, adicione as instruções using a seguir a qualquer arquivo de código que chame um tópico do Barramento de Serviço.

using System.Threading;
using System.Threading.Tasks;
using Azure.Messaging.ServiceBus;

Para enviar uma mensagem, comece criando um objeto ServiceBusClient e passe a ele a cadeia de conexão e o nome do tópico.

await using var client = new ServiceBusClient(connectionString);

Em seguida, crie um objeto ServiceBusSender invocando o método CreateSender no objeto ServiceBusClient e especificando o nome do tópico.

ServiceBusSender sender = client.CreateSender(topicName);

Você pode enviar uma mensagem ao tópico chamando o método ServiceBusSender.SendMessageAsync() e passando um ServiceBusMessage. Como em uma fila, a mensagem deve estar na forma de uma cadeia de caracteres codificada em UTF-8.

string message = "Cancel! I have changed my mind!";
var message = new ServiceBusMessage(message);

// Send the message to the topic.
await sender.SendMessageAsync(message);

Para receber mensagens de uma assinatura

Para receber uma mensagem de uma assinatura, você deve criar um objeto ServiceBusProcessor e passar a ele o nome do tópico e o nome da assinatura.

processor = client.CreateProcessor(topicName, subscriptionName, options);

Em seguida, registre um manipulador de mensagens e um manipulador de erros.

// Specify the handler method for messages.
processor.ProcessMessageAsync += MessageHandler;

// Specify the handler method for errors.
processor.ProcessErrorAsync += ErrorHandler;

Faça seu trabalho de processamento no manipulador de mensagens e, em seguida, chame o método ProcessMessageEventArgs.CompleteMessageAsync() para remover a mensagem da assinatura.

// Complete the message. The message is deleted from the subscription. 
await args.CompleteMessageAsync(args.Message);