Übung: Senden und Empfangen von Nachrichten mithilfe eines Themas

Abgeschlossen

Sie haben sich entschieden, ein Azure Service Bus-Thema zu verwenden, um Nachrichten zur Vertriebsleistung in Ihrer Vertriebsanwendung zu verteilen. Das Verkaufspersonal wird die App auf seinen mobilen Geräten verwenden, um Nachrichten zu versenden, die die Verkaufszahlen für jedes Gebiet und jeden Zeitraum zusammenfassen. Diese Nachrichten werden an Webdienste verteilt, die sich in den Geschäftsregionen des Unternehmens befinden, einschließlich Nord-, Mittel- und Südamerika und Europa.

Sie haben in Ihrem Azure-Abonnement für das Thema bereits die erforderliche Infrastruktur implementiert. Nun möchten Sie den Code schreiben, der Nachrichten an das Thema sendet und Nachrichten aus einem Abonnement abruft. Anschließend senden Sie eine Nachricht an ein Thema und rufen die Nachricht für ein bestimmtes Abonnement ab.

Stellen Sie sicher, dass Sie im richtigen Verzeichnis arbeiten, indem Sie in Azure Cloud Shell die folgenden Befehle ausführen:

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

Schreiben von Code zum Senden einer Nachricht an ein Thema

Führen Sie die folgenden Schritte aus, um die Komponente fertigzustellen, mit der Nachrichten zur Vertriebsleistung gesendet werden:

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

    const string ServiceBusConnectionString = "";
    

    Fügen Sie zwischen die Anführungszeichen die Verbindungszeichenfolge ein, die Sie in der vorherigen Übung gespeichert haben.

  2. Wenn Sie einen anderen Namen als salesperformancemessages für den Warteschlangennamen verwendet haben, sollten Sie den Wert der TopicName-Eigenschaft im Code aktualisieren:

    const string TopicName = "salesperformancemessages";
    
  3. Suchen Sie die SendPerformanceMessageAsync()-Methode. (Hinweis: Sie befindet sich in oder in der Nähe von Zeile 26.) Suchen Sie innerhalb dieser Methode die folgende Codezeile:

    // Create a Service Bus client here
    

    Ersetzen Sie diese Zeile durch diesen Code:

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

    // Create a sender here
    

    Ersetzen Sie diese Zeile durch diesen Code:

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

    // Create and send a message here
    

    Ersetzen Sie diese Zeile durch diesen Code:

    string messageBody = "Total sales for Brazil in August: $13m.";
    var message = new ServiceBusMessage(messageBody);
    
  6. Fügen Sie den folgenden Code in die nächste Zeile ein, um die Nachricht in der Konsole anzuzeigen:

    Console.WriteLine($"Sending message: {messageBody}");
    
  7. Fügen Sie den folgenden Code in die nächste Zeile ein, um die Nachricht an das Thema zu senden:

    await sender.SendMessageAsync(message);
    
  8. Überprüfen Sie, ob der endgültige Code dem folgenden Beispiel ähnelt:

    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}");
                }
            }
        }
    }
    
  9. 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 das Thema

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

    dotnet run --project performancemessagesender
    
  2. Achten Sie bei der Ausführung des Programms auf Benachrichtigungen in Cloud Shell, die angeben, dass eine Nachricht gesendet wird. Jedes Mal, wenn Sie die App ausführen, wird dem Thema eine weitere Nachricht hinzugefügt, und für jedes Abonnement wird eine Kopie verfügbar.

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

Überprüfen der Nachrichtenanzahl, bevor Sie Nachrichten für ein Abonnement abrufen

Wenn Sie Message was sent successfully sehen, führen Sie den folgenden Befehl aus, um zu ermitteln, wie viele Nachrichten sich im Abonnement Americas befinden. Denken Sie daran, <namespace-name> durch den Namen Ihres Service Bus-Namespace zu ersetzen.

az servicebus topic subscription show \
    --resource-group <rgn>[sandbox resource group name]</rgn> \
    --topic-name salesperformancemessages \
    --name Americas \
    --query messageCount \
    --namespace-name <namespace-name>

Wenn Sie Americas durch EuropeAndAsia ersetzen und den Befehl nochmal ausführen, wird für beide Abonnements die gleiche Anzahl von Nachrichten angezeigt.

Schreiben von Code zum Abrufen einer Themennachricht für ein Abonnement

Um die Komponente zu erstellen, die Nachrichten über die Vertriebsleistung abruft, führen Sie die folgenden Schritte aus:

  1. Führen Sie code . aus, um den Editor zu starten.

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

    const string ServiceBusConnectionString = "";
    

    Fügen Sie zwischen die Anführungszeichen die Verbindungszeichenfolge ein, die Sie in der vorherigen Übung gespeichert haben.

  3. Um einen Service Bus-Client zu erstellen, suchen Sie die MainAsync()-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 den 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 den folgenden Code:

    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 den folgenden Code:

    ServiceBusProcessor processor = client.CreateProcessor(TopicName, SubscriptionName, processorOptions);
    
  6. Suchen Sie die folgende Codezeile, um den Handler zu konfigurieren:

    // Configure the message and error handler to use
    

    Ersetzen Sie diese Zeile durch den 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 den folgenden Code:

    await processor.StartProcessingAsync();
    
  8. Suchen Sie die folgende Codezeile:

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

    Ersetzen Sie die Zeile durch diesen Code:

    await processor.DisposeAsync();
    await client.DisposeAsync();    
    
  9. Um eingehende Nachrichten in der Konsole anzuzeigen, suchen Sie die MessageHandler()-Methode. Sie haben diese Methode für die Verarbeitung eingehender Nachrichten registriert.

    Ersetzen Sie den Code in dieser Methode durch den folgenden Code:

    Console.WriteLine($"Received message: SequenceNumber:{args.Message.SequenceNumber} Body:{args.Message.Body}");
    
  10. Fügen Sie in der nächsten Zeile den folgenden Code hinzu, um die empfangene Nachricht aus dem Abonnement zu entfernen:

    await args.CompleteMessageAsync(args.Message);
    
  11. Überprüfen Sie, ob der endgültige Code dem folgenden Beispiel ähnelt:

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

Abrufen einer Themennachricht für ein Abonnement

  1. Führen Sie den folgenden Befehl aus, um die Komponente auszuführen, die eine Nachricht zur Vertriebsleistung für ein Abonnement abruft:

    dotnet run --project performancemessagereceiver
    

    Ihnen wird daraufhin eine Ausgabe angezeigt, die in etwa wie im folgenden Beispiel aussieht:

    Received message: SequenceNumber:1 Body:Total sales for Brazil in August: $13m.
    
  2. Wenn das Programm Benachrichtigungen über den Empfang von Nachrichten zurückgegeben hat, drücken Sie die EINGABETASTE, um die App zu beenden.

Überprüfen der Nachrichtenanzahl nach dem Abrufen einer Nachricht für ein Abonnement

Führen Sie den folgenden Befehl aus, um zu bestätigen, dass im Abonnement Americas keine Nachrichten mehr vorhanden sind. Denken Sie daran, <namespace-name> durch den Namen Ihres Service Bus-Namespace zu ersetzen.

az servicebus topic subscription show \
     --resource-group <rgn>[sandbox resource group name]</rgn> \
     --topic-name salesperformancemessages \
     --name Americas \
     --query messageCount \
     --namespace-name <namespace-name> 

Wenn Sie in diesem Code Americas durch EuropeAndAsia ersetzen, um die aktuelle Anzahl der Nachrichten für das Abonnement EuropeAndAsia anzuzeigen, sehen Sie, dass die Anzahl der Nachrichten 1 beträgt. Im vorhergehenden Code wurde nur Americas zum Abrufen von Themennachrichten festgelegt, sodass diese Nachricht immer noch auf EuropeAndAsia zum Abrufen wartet.