Exercice : Envoi et réception de messages à l’aide d’une rubrique

Effectué

Vous avez décidé d’utiliser une rubrique Azure Service Bus pour distribuer les messages relatifs aux performances des ventes dans votre application de force de vente. Les commerciaux vont utiliser l’application sur leurs appareils mobiles pour envoyer des messages récapitulant les chiffres des ventes pour chaque région et chaque période. Ces messages sont distribués à des services web situés dans les régions d’exploitation de la société, notamment les Amériques et l’Europe.

Vous avez déjà implémenté l’infrastructure nécessaire dans vos abonnements Azure pour la rubrique. Vous voulez maintenant écrire le code qui envoie des messages à la rubrique et celui qui récupère des messages dans un abonnement. Ensuite, vous enverrez un message à une rubrique et le récupérerez pour un abonnement spécifique.

Vérifiez que vous vous trouvez dans le bon répertoire. Pour cela, exécutez les commandes suivantes dans Azure Cloud Shell :

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

Écriture de code permettant d’envoyer un message à une rubrique

Procédez comme suit pour terminer le composant qui envoie des messages relatifs aux performances de ventes :

  1. Dans l’éditeur Azure Cloud Shell, ouvrez performancemessagesender/Program.cs et recherchez la ligne de code suivante :

    const string ServiceBusConnectionString = "";
    

    Collez la chaîne de connexion que vous avez enregistrée dans l’exercice précédent entre les guillemets.

  2. Si vous avez utilisé un autre nom que salesperformancemessages pour la file d’attente, mettez à jour la valeur de la propriété TopicName dans le code :

    const string TopicName = "salesperformancemessages";
    
  3. Recherchez la méthode SendPerformanceMessageAsync(). (Indice : Elle se trouve à la ligne 26 ou à proximité.) Dans cette méthode, recherchez la ligne de code suivante :

    // Create a Service Bus client here
    

    Remplacez cette ligne de code par le code suivant :

    // 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. Dans la méthode SendPerformanceMessageAsync(), recherchez la ligne de code suivante :

    // Create a sender here
    

    Remplacez cette ligne de code par le code suivant :

    await using ServiceBusSender sender = client.CreateSender(TopicName);
    
  5. Dans le bloc try...catch, recherchez la ligne de code suivante :

    // Create and send a message here
    

    Remplacez cette ligne de code par le code suivant :

    string messageBody = "Total sales for Brazil in August: $13m.";
    var message = new ServiceBusMessage(messageBody);
    
  6. Pour afficher le message dans la console, insérez le code suivant sur la ligne suivante :

    Console.WriteLine($"Sending message: {messageBody}");
    
  7. Pour envoyer le message à la rubrique, insérez le code suivant sur la ligne suivante :

    await sender.SendMessageAsync(message);
    
  8. Vérifiez que votre code final se présente ainsi :

    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=xxxxxx";
            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. Pour enregistrer vos modifications, sélectionnez Ctrl+S, puis Ctrl+Q pour fermer l’éditeur.

Envoyer un message à la rubrique

  1. Pour exécuter le composant qui envoie un message relatif à une vente, exécutez la commande suivante dans Cloud Shell :

    dotnet run --project performancemessagesender
    
  2. À mesure que le programme s’exécute, observez dans Cloud Shell les notifications qui indiquent qu’un message est envoyé. Chaque fois que vous exécutez l’application, un autre message est ajouté à la rubrique. Une copie devient disponible pour chaque abonnement.

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

Vérification du nombre de messages avant récupération des messages d’un abonnement

Lorsque le message Message was sent successfully apparaît, exécutez la commande suivante pour voir combien de messages se trouvent dans l’abonnement Americas. N’oubliez pas de remplacer <namespace-name> par le nom de votre espace de noms 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 vous remplacez Americas par EuropeAndAsia et réexécutez la commande, vous voyez normalement que les deux abonnements comportent le même nombre de messages.

Écriture de code permettant de récupérer un message de rubrique pour un abonnement

Procédez comme suit pour créer le composant qui récupère des messages relatifs aux performances de ventes :

  1. Exécutez code . pour lancer l’éditeur.

  2. Dans l’éditeur, ouvrez performancemessagereceiver/Program.cs et recherchez la ligne de code suivante :

    const string ServiceBusConnectionString = "";
    

    Collez la chaîne de connexion que vous avez enregistrée dans l’exercice précédent entre les guillemets.

  3. Pour créer un client Service Bus, recherchez la méthode MainAsync(). Dans cette méthode, recherchez la ligne de code suivante :

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

    Remplacez cette ligne par le code suivant :

    var client = new ServiceBusClient(ServiceBusConnectionString);
    
  4. Pour configurer les options de gestion des messages, recherchez la ligne de code suivante :

    // Create the options to use for configuring the processor
    

    Remplacez cette ligne par le code suivant :

    var processorOptions = new ServiceBusProcessorOptions
    {
        MaxConcurrentCalls = 1,
        AutoCompleteMessages = false
    };
    
  5. Pour créer un processeur, recherchez la ligne de code suivante :

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

    Remplacez cette ligne par le code suivant :

    ServiceBusProcessor processor = client.CreateProcessor(TopicName, SubscriptionName, processorOptions);
    
  6. Pour configurer le gestionnaire, recherchez la ligne de code suivante :

    // Configure the message and error handler to use
    

    Remplacez cette ligne par le code suivant :

    processor.ProcessMessageAsync += MessageHandler;
    processor.ProcessErrorAsync += ErrorHandler;
    
  7. Pour commencer le traitement, recherchez la ligne de code suivante :

    // Start processing
    

    Remplacez cette ligne par le code suivant :

    await processor.StartProcessingAsync();
    
  8. Recherchez la ligne de code suivante :

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

    Remplacez cette ligne par le code suivant :

    await processor.DisposeAsync();
    await client.DisposeAsync();    
    
  9. Pour afficher les messages entrants dans la console, recherchez la méthode MessageHandler(). Vous avez enregistré cette méthode pour gérer les messages entrants.

    Remplacez tout le code de cette méthode par le code suivant :

    Console.WriteLine($"Received message: SequenceNumber:{args.Message.SequenceNumber} Body:{args.Message.Body}");
    
  10. Pour supprimer le message reçu de l’abonnement, sur la ligne suivante, ajoutez le code suivant :

    await args.CompleteMessageAsync(args.Message);
    
  11. Vérifiez que votre code final se présente ainsi :

    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=xxxxxx";
            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. Pour enregistrer vos modifications, sélectionnez Ctrl+S, puis Ctrl+Q pour fermer l’éditeur.

Récupération d’un message de rubrique pour un abonnement

  1. Pour exécuter le composant qui récupère un message relatif aux performances de ventes d’un abonnement, exécutez la commande suivante :

    dotnet run --project performancemessagereceiver
    

    Le résultat ressemble à l’exemple suivant :

    Received message: SequenceNumber:1 Body:Total sales for Brazil in August: $13m.
    
  2. Quand le programme a retourné des notifications indiquant qu’il reçoit des messages, appuyez sur Entrée pour arrêter l’application.

Vérification du nombre de messages après récupération des messages d’un abonnement

Exécutez la commande suivante pour vérifier qu’il ne reste aucun message dans l’abonnement Americas. Veillez à remplacer <namespace-name> par le nom de votre espace de noms 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 vous remplacez Americas par EuropeAndAsia dans le code suivant pour voir le nombre actuel de messages de l’abonnement EuropeAndAsia, vous obtenez 1. Dans le code précédent, seul Americas était défini pour récupérer les messages de rubrique. Le message attend donc EuropeAndAsia pour le récupérer.