Übung: Senden und Empfangen von Nachrichten mithilfe einer Warteschlange

Abgeschlossen

Sie haben sich für die Verwendung einer Service Bus-Warteschlange entschieden, um Nachrichten zu den einzelnen Verkäufen zwischen der mobilen App, die von Ihren Vertriebsmitarbeiter*innen genutzt wird, und dem in Azure gehosteten Webdienst zu verarbeiten, der Details zu den einzelnen Verkäufen in einer Azure SQL-Datenbank-Instanz speichert.

In der vorherigen Übung haben Sie die erforderlichen Objekte in Ihrem Azure-Abonnement implementiert. Nun möchten Sie Code schreiben, mit dem Nachrichten an diese Warteschlange gesendet und daraus abgerufen werden.

In dieser Lerneinheit erstellen Sie zwei Konsolenanwendungen: eine, die Nachrichten in einer Service Bus-Warteschlange platziert, und eine, die sie aus einer Service Bus-Warteschlange abruft. Die Anwendungen sind Teil einer einzelnen .NET Core-Lösung.

Abrufen der Verbindungszeichenfolge für den Service Bus-Namespace

Sie müssen zwei Informationen in Ihren beiden Konsolen-Apps konfigurieren, um auf Ihren Service Bus-Namespace zuzugreifen und die Warteschlange in diesem Namespace zu verwenden:

  • Endpunkt für Ihren Namespace
  • Freigegebener Zugriffsschlüssel für die Authentifizierung

Sie können diese Werte aus der Verbindungszeichenfolge abrufen.

  1. Wählen Sie rechts im Bildschirm im Cloud Shell-Fenster das Symbol Mehr (...) und anschließend Einstellungen>Zur klassischen Version wechseln aus.

  2. Führen Sie den folgenden Befehl aus, und ersetzen Sie dabei <namespace-name> durch den Service Bus-Namespace, den Sie in der letzten Übung erstellt haben.

    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>
    

    Die letzte Zeile in der Antwort ist die Verbindungszeichenfolge, die den Endpunkt für Ihren Namespace und den gemeinsam genutzten Zugriffsschlüssel enthält. Dies sollte dem folgenden Beispiel ähneln:

    Endpoint=sb://example.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=xxxxxxxx
    
  3. Kopieren Sie die Verbindungszeichenfolge aus Cloud Shell. Sie benötigen diese Verbindungszeichenfolge in diesem Modul mehrmals, daher sollten Sie sie an einem schnell zugänglichen Ort speichern.

Klonen und Öffnen der Startanwendung

Hinweis

Der Einfachheit halber werden Sie in den folgenden Aufgaben angewiesen, die Verbindungszeichenfolge in der Datei Program.cs beider Konsolenanwendungen hart zu codieren. In einer Produktionsanwendung sollten Sie eine Konfigurationsdatei oder einen Azure Key Vault-Tresor verwenden, um die Verbindungszeichenfolge zu speichern.

  1. Führen Sie den folgenden Befehl in Cloud Shell aus, um die Git-Projektlösung zu klonen:

    cd ~
    git clone https://github.com/MicrosoftDocs/mslearn-connect-services-together.git
    
  2. Führen Sie den folgenden Befehl aus, um zum Startordner in Ihrem geklonten Projekt zu wechseln und ihn im Cloud Shell-Editor zu öffnen.

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

Schreiben von Code zum Senden einer Nachricht an eine Warteschlange

  1. Öffnen Sie im Cloud Shell-Editor privatemessagesender/Program.cs, und suchen Sie die folgende Codezeile:

    const string ServiceBusConnectionString = "";
    

    Fügen Sie die Verbindungszeichenfolge zwischen den Anführungszeichen ein.

  2. Wenn Sie anderen Namen als salesmessages als Warteschlangennamen verwendet haben, sollten Sie den Wert der QueueName-Eigenschaft im Code aktualisieren:

    const string QueueName = "salesmessages";
    
  3. Um die Komponente zu vervollständigen, die Nachrichten zu Verkäufen sendet, müssen Sie einen await-Operator hinzufügen, um die Auswertung der asynchronen Methode anzuhalten, bis der asynchrone Vorgang abgeschlossen ist. Suchen Sie die SendSalesMessageAsync()-Methode. Suchen Sie in dieser Methode nach der folgenden Codezeile:

    // Create a Service Bus client here
    

    Ersetzen Sie diese Codezeile durch den folgenden Code:

    // 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. Suchen Sie in der SendSalesMessageAsync()-Methode die folgende Codezeile:

    // Create a sender here
    

    Ersetzen Sie diesen Kommentar durch den folgenden Code:

    await using ServiceBusSender sender = client.CreateSender(QueueName);
    
  5. Suchen Sie im try...catch-Block die folgende Codezeile:

    // Create and send a message here
    

    Ersetzen Sie diese Codezeile durch die folgenden Codezeilen:

    string messageBody = $"$10,000 order for bicycle parts from retailer Adventure Works.";
    var message = new ServiceBusMessage(messageBody);
    
  6. Fügen Sie den folgenden Code direkt unter dem hinzugefügten Code in eine neue Zeile ein, um die Nachricht in der Konsole anzuzeigen:

    Console.WriteLine($"Sending message: {messageBody}");
    
  7. Geben Sie den folgenden Code in die nächste Zeile ein:

    await sender.SendMessageAsync(message);
    
  8. Um Absender- und Clientobjekte zu entfernen, suchen Sie am Ende der Datei den folgenden Kommentar:

    // Close the connection to the sender here
    

    Ersetzen Sie diese Zeile durch folgenden Code:

    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. Prüfen Sie, ob Ihr endgültiger Code für privatemessagesender/Program.cs dem folgenden Beispiel ähnelt:

    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. Drücken Sie STRG+S, um Ihre Änderungen zu speichern. Drücken Sie anschließend STRG+Q, um den Editor zu schließen.

Senden einer Nachricht an die Warteschlange

  1. Führen Sie in der Cloud Shell den folgenden Befehl aus, um eine Nachricht über einen Verkauf zu senden. Die erste Zeile stellt sicher, dass Sie sich im richtigen Pfad befinden.

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

    Hinweis

    Wenn Sie die Apps in dieser Übung zum ersten Mal ausführen, erlauben Sie dotnet, Pakete aus Remotequellen wiederherzustellen und die Apps zu erstellen.

    Während das Programm ausgeführt wird, werden Nachrichten an die Konsole ausgegeben, die angeben, dass die App eine Nachricht sendet:

    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. Wenn die App fertig ist, führen Sie den folgenden Befehl aus. Ersetzen Sie dabei <namespace-name> durch den Namen Ihres Service Bus-Namespace. Dieser Befehl gibt die Anzahl der Nachrichten zurück, die sich in der Warteschlange befinden.

    az servicebus queue show \
        --resource-group "<rgn>[sandbox resource group name]</rgn>" \
        --name salesmessages \
        --query messageCount \
        --namespace-name <namespace-name>
    
  3. Führen Sie den Befehl dotnet run aus Schritt 1 noch einmal aus, und führen Sie dann den Befehl servicebus queue show noch einmal aus. Bei jeder Ausführung der dotnet-App wird der Warteschlange eine neue Nachricht hinzugefügt. Die Erhöhung des messageCount wird bei jeder Ausführung des Azure-Befehls angezeigt.

Schreiben von Code für das Empfangen von Nachrichten aus der Warteschlange

  1. Führen Sie den folgenden Befehl aus, um den Editor erneut zu öffnen:

    code .
    
  2. Öffnen Sie privatemessagereceiver/Program.cs im Editor, und suchen Sie die folgende Codezeile:

    const string ServiceBusConnectionString = "";
    

    Fügen Sie die zuvor gespeicherte Verbindungszeichenfolge zwischen den Anführungszeichen ein.

  3. Suchen Sie die ReceiveSalesMessageAsync()-Methode. Suchen Sie in dieser Methode nach der folgenden Codezeile:

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

    Ersetzen Sie diese Zeile durch folgenden Code:

    var client = new ServiceBusClient(ServiceBusConnectionString);
    
  4. Um Optionen für die Nachrichtenverarbeitung zu konfigurieren, suchen Sie die folgende Codezeile:

    // Create the options to use for configuring the processor
    

    Ersetzen Sie diese Zeile durch die folgenden Codezeilen:

    var processorOptions = new ServiceBusProcessorOptions
    {
        MaxConcurrentCalls = 1,
        AutoCompleteMessages = false
    };
    
  5. Suchen Sie die folgende Codezeile, um einen Prozessor zu erstellen:

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

    Ersetzen Sie diese Zeile durch folgenden Code:

    await using ServiceBusProcessor processor = client.CreateProcessor(QueueName, processorOptions);
    
  6. Suchen Sie die folgende Codezeile, um die Handler zu konfigurieren:

    // Configure the message and error handler to use
    

    Ersetzen Sie diese Zeile durch folgenden Code:

    processor.ProcessMessageAsync += MessageHandler;
    processor.ProcessErrorAsync += ErrorHandler;
    
  7. Suchen Sie die folgende Codezeile, um die Verarbeitung zu starten:

    // Start processing
    

    Ersetzen Sie diese Zeile durch folgenden Code:

    await processor.StartProcessingAsync();
    
  8. Um die Verbindung mit Service Bus zu schließen, suchen Sie die folgende Codezeile:

    // Close the processor here
    

    Ersetzen Sie diese Zeile durch folgenden Code:

    await processor.CloseAsync();
    
  9. Überprüfen Sie den Code in der MessageHandler-Methode:

    // 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. Überprüfen Sie den Code in der ErrorHandler-Methode:

    // handle any errors when receiving messages
    static Task ErrorHandler(ProcessErrorEventArgs args)
    {
        // print the exception message
        Console.WriteLine(args.Exception.ToString());
        return Task.CompletedTask;
    }    
    
  11. Prüfen Sie, ob Ihr endgültiger Code für privatemessagereceiver/Program.cs dem folgenden Beispiel ähnelt:

    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. Drücken Sie STRG+S, um Ihre Änderungen zu speichern. Drücken Sie anschließend STRG+Q, um den Editor zu schließen.

Empfangen einer Nachricht aus der Warteschlange

  1. Führen Sie den folgenden Befehl in Cloud Shell aus, um die Komponente auszuführen, die eine Nachricht zu einem Verkauf empfängt:

    dotnet run --project privatemessagereceiver
    
  2. Überprüfen Sie die Benachrichtigungen in Cloud Shell. Wechseln Sie im Azure-Portal zu Ihrem Service Bus-Namespace, und überprüfen Sie Ihr Diagramm Nachrichten:

    Received: $10,000 order for bicycle parts from retailer Adventure Works.
    
  3. Wenn Sie sehen, dass die Nachrichten in Cloud Shell empfangen wurden, drücken Sie die EINGABETASTE, um die App zu beenden.

Überprüfen der Nachrichtenanzahl

Führen Sie den folgenden Code aus, um zu überprüfen, ob alle Nachrichten aus der Warteschlange entfernt wurden. Denken Sie daran, <namespace-name> durch Ihren Service Bus-Namespace zu ersetzen.

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

0 wird ausgegeben, wenn alle Nachrichten entfernt wurden.

Sie haben Code geschrieben, der eine Nachricht zu einzelnen Verkäufen an eine Service Bus-Warteschlange sendet. In der verteilten Vertriebsanwendung sollten Sie diesen Code in der mobilen App schreiben, die von den Vertriebsmitarbeitern auf Geräten genutzt wird.

Sie haben auch Code geschrieben, der eine Nachricht von der Service Bus-Warteschlange empfängt. In der verteilten Vertriebsanwendung sollten Sie diesen Code in dem Webdienst schreiben, der in Azure ausgeführt wird und mit dem empfangene Nachrichten verarbeitet werden.