Ćwiczenie — wysyłanie i odbieranie komunikatów przy użyciu tematu

Ukończone

Podjęto decyzję o użyciu tematu usługi Azure Service Bus w celu dystrybucji komunikatów o wydajności sprzedaży w aplikacji salesforce. Pracownicy działu sprzedaży będą używać aplikacji na swoich urządzeniach przenośnych do wysyłania komunikatów podsumowujących dane sprzedaży dla każdego obszaru i okresu. Te komunikaty są dystrybuowane do usług internetowych, które znajdują się w regionach operacyjnych firmy, w tym w Ameryce i Europie.

Zaimplementowano już niezbędną infrastrukturę w subskrypcjach platformy Azure dla tego tematu. Teraz chcesz napisać kod, który wysyła komunikaty do tematu i pisać kod, który pobiera komunikaty z subskrypcji. Następnie wyślesz komunikat do tematu i pobierzesz komunikat dla określonej subskrypcji.

Upewnij się, że pracujesz w poprawnym katalogu, uruchamiając następujące polecenia w usłudze Azure Cloud Shell:

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

Pisanie kodu w celu wysłania komunikatu do tematu

Aby ukończyć składnik, który wysyła komunikaty dotyczące wydajności sprzedaży, wykonaj następujące kroki:

  1. W edytorze usługi Azure Cloud Shell otwórz plik performancemessagesender/Program.cs i znajdź następujący wiersz kodu:

    const string ServiceBusConnectionString = "";
    

    Między cudzysłowami wklej parametry połączenia zapisane w poprzednim ćwiczeniu.

  2. Jeśli użyto nazwy innej niż salesperformancemessages dla nazwy kolejki, zaktualizuj wartość właściwości TopicName w kodzie:

    const string TopicName = "salesperformancemessages";
    
  3. Znajdź metodę SendPerformanceMessageAsync() . (Wskazówka: Znajduje się w lub w pobliżu wiersza 26). W ramach tej metody znajdź następujący wiersz kodu:

    // Create a Service Bus client here
    

    Zastąp ten wiersz kodu następującym kodem:

    // 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. W metodzie SendPerformanceMessageAsync() znajdź następujący wiersz kodu:

    // Create a sender here
    

    Zastąp ten wiersz kodu następującym kodem:

    await using ServiceBusSender sender = client.CreateSender(TopicName);
    
  5. try...catch W bloku znajdź następujący wiersz kodu:

    // Create and send a message here
    

    Zastąp ten wiersz kodu następującym kodem:

    string messageBody = "Total sales for Brazil in August: $13m.";
    var message = new ServiceBusMessage(messageBody);
    
  6. Aby wyświetlić komunikat w konsoli programu , wstaw następujący kod w następnym wierszu:

    Console.WriteLine($"Sending message: {messageBody}");
    
  7. Aby wysłać komunikat do tematu, wstaw następujący kod w następnym wierszu:

    await sender.SendMessageAsync(message);
    
  8. Sprawdź, czy końcowy kod przypomina następujący przykład:

    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. Aby zapisać zmiany, naciśnij klawisze Ctrl+S, a następnie naciśnij klawisze Ctrl+Q, aby zamknąć edytor.

Wysyłanie komunikatu do tematu

  1. Aby uruchomić składnik, który wysyła komunikat o sprzedaży, uruchom następujące polecenie w usłudze Cloud Shell:

    dotnet run --project performancemessagesender
    
  2. Podczas wykonywania programu poszukaj powiadomień w usłudze Cloud Shell, które wskazują, że wiadomość jest wysyłana. Za każdym razem, gdy uruchamiasz aplikację, do tematu jest dodawany kolejny komunikat, a kopia staje się dostępna dla każdej subskrypcji.

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

Sprawdź liczbę komunikatów przed pobraniem komunikatów dla subskrypcji

Po wyświetleniu polecenia Message was sent successfullyuruchom następujące polecenie, aby zobaczyć liczbę komunikatów w Americas subskrypcji. Pamiętaj, aby zastąpić <przestrzeń nazw przestrzeni nazw> przestrzenią nazw usługi 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>

Jeśli zastąpisz Americas element i EuropeAndAsia ponownie uruchomisz polecenie, zobaczysz, że obie subskrypcje mają taką samą liczbę komunikatów.

Pisanie kodu w celu pobrania komunikatu tematu dla subskrypcji

Aby utworzyć składnik, który pobiera komunikaty dotyczące wydajności sprzedaży, wykonaj następujące kroki:

  1. Uruchom polecenie code . , aby uruchomić edytor.

  2. W edytorze otwórz plik performancemessagereceiver/Program.cs i znajdź następujący wiersz kodu:

    const string ServiceBusConnectionString = "";
    

    Między znakami cudzysłowu wklej parametry połączenia zapisane w poprzednim ćwiczeniu.

  3. Aby utworzyć klienta usługi Service Bus, znajdź metodę MainAsync() . W ramach tej metody znajdź następujący wiersz kodu:

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

    Zastąp ten wiersz następującym kodem:

    var client = new ServiceBusClient(ServiceBusConnectionString);
    
  4. Aby skonfigurować opcje obsługi komunikatów, znajdź następujący wiersz kodu:

    // Create the options to use for configuring the processor
    

    Zastąp ten wiersz następującym kodem:

    var processorOptions = new ServiceBusProcessorOptions
    {
        MaxConcurrentCalls = 1,
        AutoCompleteMessages = false
    };
    
  5. Aby utworzyć procesor, znajdź następujący wiersz kodu:

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

    Zastąp ten wiersz następującym kodem:

    ServiceBusProcessor processor = client.CreateProcessor(TopicName, SubscriptionName, processorOptions);
    
  6. Aby skonfigurować procedurę obsługi, znajdź następujący wiersz kodu:

    // Configure the message and error handler to use
    

    Zastąp ten wiersz następującym kodem:

    processor.ProcessMessageAsync += MessageHandler;
    processor.ProcessErrorAsync += ErrorHandler;
    
  7. Aby rozpocząć przetwarzanie, znajdź następujący wiersz kodu:

    // Start processing
    

    Zastąp ten wiersz następującym kodem:

    await processor.StartProcessingAsync();
    
  8. Poszukaj następującego wiersza kodu:

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

    Zastąp wiersz następującym kodem:

    await processor.DisposeAsync();
    await client.DisposeAsync();    
    
  9. Aby wyświetlić komunikaty przychodzące w konsoli programu , znajdź metodę MessageHandler() . Ta metoda została zarejestrowana w celu obsługi komunikatów przychodzących.

    Zastąp cały kod w tej metodzie następującym kodem:

    Console.WriteLine($"Received message: SequenceNumber:{args.Message.SequenceNumber} Body:{args.Message.Body}");
    
  10. Aby usunąć odebrany komunikat z subskrypcji, w następnym wierszu dodaj następujący kod:

    await args.CompleteMessageAsync(args.Message);
    
  11. Sprawdź, czy końcowy kod przypomina następujący przykład:

    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. Aby zapisać zmiany, naciśnij klawisze Ctrl+S, a następnie naciśnij klawisze Ctrl+Q, aby zamknąć edytor.

Pobieranie komunikatu tematu dla subskrypcji

  1. Aby uruchomić składnik, który pobiera komunikat o wydajności sprzedaży dla subskrypcji, uruchom następujące polecenie:

    dotnet run --project performancemessagereceiver
    

    Zostaną wyświetlone dane wyjściowe podobne do następujących:

    Received message: SequenceNumber:1 Body:Total sales for Brazil in August: $13m.
    
  2. Gdy program zwrócił powiadomienia, że odbiera komunikaty, naciśnij Enter , aby zatrzymać aplikację.

Sprawdź liczbę komunikatów po pobraniu komunikatu dla subskrypcji

Uruchom następujące polecenie, aby potwierdzić, że w subskrypcji nie ma żadnych pozostałych komunikatów Americas . Pamiętaj, aby zastąpić <przestrzeń nazw przestrzeni nazw przestrzenią nazw> usługi 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> 

Jeśli zastąpisz Americas ciąg ciągiem EuropeAndAsia w tym kodzie, aby zobaczyć bieżącą liczbę komunikatów dla EuropeAndAsia subskrypcji, zobaczysz, że liczba komunikatów to 1. W poprzednim kodzie ustawiono tylko Americas opcję pobierania komunikatów tematu, więc komunikat nadal czeka na EuropeAndAsia jego pobranie.