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

Effectué

Vous avez choisi d’utiliser une file d’attente Service Bus pour gérer les messages sur les ventes individuelles entre l’application mobile, utilisée par votre personnel commercial, et le service web hébergé dans Azure, qui stocke les informations sur chaque vente dans une instance Azure SQL Database.

Dans l’exercice précédent, vous avez implémenté les objets nécessaires dans votre abonnement Azure. Maintenant, vous voulez créer un code qui envoie des messages à cette file d’attente et récupère les messages.

Dans cette unité, vous allez créer deux applications console : une qui place des messages dans une file d’attente Service Bus et une autre qui récupère des messages dans une file d’attente Service Bus. Les applications font partie d’une seule solution.NET Core.

Récupération de la chaîne de connexion à l’espace de noms Service Bus

Vous devez configurer deux informations dans vos deux applications console pour pouvoir accéder à votre espace de noms Service Bus et utiliser la file d’attente qui s’y trouve :

  • Point de terminaison de votre espace de noms
  • Clé d’accès partagée pour l’authentification

Vous pouvez récupérer ces valeurs à partir de la chaîne de connexion.

  1. Dans la fenêtre Cloud Shell située à droite de l’écran, sélectionnez l’icône Plus (...), puis Paramètres>Accéder à la version classique.

  2. Exécutez la commande suivante en remplaçant <namespace-name> par l’espace de noms Service Bus que vous avez créé dans l’exercice précédent.

    az servicebus namespace authorization-rule keys list \
        --resource-group "<rgn>[sandbox resource group name]</rgn>" \
        --name RootManageSharedAccessKey \
        --query primaryConnectionString \
        --output tsv \
        --namespace-name <namespace-name>
    

    La dernière ligne de la réponse est la chaîne de connexion, qui comprend le point de terminaison de votre espace de noms et la clé d’accès partagé. Elle doit ressembler à l’exemple suivant :

    Endpoint=sb://example.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=xxxxxxxx
    
  3. Copiez la chaîne de connexion à partir de Cloud Shell. Vous aurez besoin de cette chaîne de connexion à plusieurs reprises durant ce module, vous pouvez donc l’enregistrer à un endroit facile d’accès.

Cloner et ouvrir l’application de démarrage

Notes

Dans un souci de simplicité, il vous est demandé dans les tâches suivantes de coder en dur la chaîne de connexion dans le fichier Program.cs des deux applications console. Dans une application de production, vous devez utiliser un fichier de configuration ou Azure Key Vault pour stocker la chaîne de connexion.

  1. Exécutez la commande suivante dans Cloud Shell pour cloner la solution du projet Git :

    cd ~
    git clone https://github.com/MicrosoftDocs/mslearn-connect-services-together.git
    
  2. Exécutez la commande suivante pour accéder au dossier start dans votre projet cloné et ouvrir l’éditeur 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 file d’attente

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

    const string ServiceBusConnectionString = "";
    

    Copiez la chaîne de connexion entre les guillemets.

  2. Si vous avez utilisé un nom différent de salesmessages pour le nom de la file d’attente, mettez à jour la valeur de la propriété QueueName dans le code :

    const string QueueName = "salesmessages";
    
  3. Pour terminer le composant qui envoie des messages sur les ventes, vous devez ajouter un opérateur await pour interrompre l’évaluation de la méthode async jusqu’à ce que l’opération asynchrone se termine. Recherchez la méthode SendSalesMessageAsync(). 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 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);
    
  4. Dans la méthode SendSalesMessageAsync(), recherchez la ligne de code suivante :

    // Create a sender here
    

    Remplacez ce commentaire par le code suivant :

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

    // Create and send a message here
    

    Remplacez cette ligne de code par les lignes de code suivantes :

    string messageBody = $"$10,000 order for bicycle parts from retailer Adventure Works.";
    var message = new ServiceBusMessage(messageBody);
    
  6. Insérez le code suivant sur une nouvelle ligne, juste au-dessous de celles que vous venez d’ajouter, pour afficher le message dans la console :

    Console.WriteLine($"Sending message: {messageBody}");
    
  7. Insérez le code suivant sur la ligne suivante :

    await sender.SendMessageAsync(message);
    
  8. Pour supprimer des objets sender et client, recherchez le commentaire suivant à la fin du fichier :

    // Close the connection to the sender here
    

    Remplacez cette ligne par le code suivant :

    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();
    }
    
  9. Vérifiez que le code final de privatemessagesender/Program.cs se présente ainsi :

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

Envoyer un message vers la file d’attente

  1. Dans Cloud Shell, exécutez la commande suivante pour envoyer un message concernant une vente. La première ligne vérifie que vous êtes dans le chemin correct.

    cd ~/mslearn-connect-services-together/implement-message-workflows-with-service-bus/src/start
    dotnet run --project ./privatemessagesender
    

    Notes

    La première fois que vous exécutez les applications de cet exercice, autorisez dotnet à restaurer des packages provenant de sources distantes et à générer les applications.

    Au fur et à mesure que le programme s’exécute, des messages s’affichent dans la console pour indiquer que l’application envoie un message :

    Sending a message to the Sales Messages queue...
    Sending message: $10,000 order for bicycle parts from retailer Adventure Works.
    Message was sent successfully.
    
  2. Quand l’application a terminé, exécutez la commande suivante en remplaçant <namespace-name> par le nom de votre espace de noms Service Bus. Cette commande retourne le nombre de messages qui se trouvent dans la file d’attente.

    az servicebus queue show \
        --resource-group "<rgn>[sandbox resource group name]</rgn>" \
        --name salesmessages \
        --query messageCount \
        --namespace-name <namespace-name>
    
  3. Réexécutez la commande dotnet run de l’étape 1, puis réexécutez la commande servicebus queue show. Chaque fois que vous exécutez l’application dotnet, un nouveau message est ajouté à la file d’attente. Vous allez voir que messageCount augmente chaque fois que vous exécutez la commande Azure.

Écrire du code pour recevoir des messages de la file d’attente

  1. Exécutez la commande suivante pour rouvrir l’éditeur :

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

    const string ServiceBusConnectionString = "";
    

    Collez la chaîne de connexion que vous avez enregistrée entre les guillemets.

  3. Recherchez la méthode ReceiveSalesMessageAsync(). 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 de code par les suivantes :

    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 :

    await using ServiceBusProcessor processor = client.CreateProcessor(QueueName, processorOptions);
    
  6. Pour configurer les gestionnaires, 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. Pour fermer la connexion à Service Bus, recherchez la ligne de code suivante :

    // Close the processor here
    

    Remplacez cette ligne par le code suivant :

    await processor.CloseAsync();
    
  9. Vérifiez le code de la méthode MessageHandler :

    // 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. Vérifiez le code de la méthode ErrorHandler :

    // handle any errors when receiving messages
    static Task ErrorHandler(ProcessErrorEventArgs args)
    {
        // print the exception message
        Console.WriteLine(args.Exception.ToString());
        return Task.CompletedTask;
    }    
    
  11. Vérifiez que le code final de privatemessagereceiver/Program.cs se présente ainsi :

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

Réception d’un message de la file d’attente

  1. Pour exécuter le composant qui reçoit un message relatif à une vente, exécutez cette commande dans Cloud Shell :

    dotnet run --project privatemessagereceiver
    
  2. Vérifiez les notifications dans Cloud Shell. Sur le Portail Azure, accédez à votre espace de noms Service Bus et consultez votre tableau Messages :

    Received: $10,000 order for bicycle parts from retailer Adventure Works.
    
  3. Quand vous voyez que les messages ont été reçus dans Cloud Shell, appuyez sur Entrée pour arrêter l’application.

Vérification du nombre de messages

Exécutez le code suivant pour vérifier que tous les messages ont été supprimés de la file d’attente. N’oubliez pas de remplacer <namespace-name> par votre espace de noms Service Bus.

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

La sortie est 0 si tous les messages ont été supprimés.

Vous avez écrit un code qui envoie un message relatif aux ventes individuelles à une file d’attente Service Bus. Dans l’application distribuée de la force de vente, vous devez écrire le code suivant dans l’application mobile utilisée par le personnel de vente sur les appareils.

Vous avez également écrit du code qui reçoit un message de la file d’attente Service Bus. Dans l’application distribuée de la force de vente, vous devez écrire le code suivant dans le service web qui s’exécute dans Azure et traite les messages reçus.