Ćwiczenie — wysyłanie i odbieranie komunikatów przy użyciu tematu
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:
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.
Jeśli użyto nazwy innej niż salesperformancemessages dla nazwy kolejki, zaktualizuj wartość właściwości
TopicName
w kodzie:const string TopicName = "salesperformancemessages";
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);
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);
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);
Aby wyświetlić komunikat w konsoli programu , wstaw następujący kod w następnym wierszu:
Console.WriteLine($"Sending message: {messageBody}");
Aby wysłać komunikat do tematu, wstaw następujący kod w następnym wierszu:
await sender.SendMessageAsync(message);
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}"); } } } }
Aby zapisać zmiany, naciśnij klawisze Ctrl+S, a następnie naciśnij klawisze Ctrl+Q, aby zamknąć edytor.
Wysyłanie komunikatu do tematu
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
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 successfully
uruchom 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:
Uruchom polecenie
code .
, aby uruchomić edytor.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.
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);
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 };
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);
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;
Aby rozpocząć przetwarzanie, znajdź następujący wiersz kodu:
// Start processing
Zastąp ten wiersz następującym kodem:
await processor.StartProcessingAsync();
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();
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}");
Aby usunąć odebrany komunikat z subskrypcji, w następnym wierszu dodaj następujący kod:
await args.CompleteMessageAsync(args.Message);
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; } } }
Aby zapisać zmiany, naciśnij klawisze Ctrl+S, a następnie naciśnij klawisze Ctrl+Q, aby zamknąć edytor.
Pobieranie komunikatu tematu dla subskrypcji
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.
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.