Oefening: berichten verzenden en ontvangen met behulp van een wachtrij

Voltooid

U hebt ervoor gekozen om een Service Bus-wachtrij te gebruiken voor het afhandelen van berichten over afzonderlijke verkopen tussen de mobiele app, die uw verkoopmedewerkers gebruiken en de webservice die wordt gehost in Azure, waarin details over elke verkoop in een Azure SQL Database-exemplaar worden opgeslagen.

In de vorige oefening hebt u de benodigde objecten geïmplementeerd in uw Azure-abonnement. Nu wilt u code schrijven die berichten naar de wachtrij verzendt en berichten ophaalt.

In deze les bouwt u twee consoletoepassingen: één toepassing plaatst berichten in een Service Bus-wachtrij en één toepassing haalt berichten op uit een Service Bus-wachtrij. De toepassingen maken deel uit van een enkele .NET Core-oplossing.

De verbindingsreeks ophalen naar de Service Bus-naamruimte

U moet twee stukjes informatie in uw twee console-apps configureren om toegang te krijgen tot uw Service Bus-naamruimte en om de wachtrij in die naamruimte te gebruiken:

  • Eindpunt voor uw naamruimte
  • Gedeelde toegangssleutel voor verificatie

U kunt deze waarden ophalen uit de verbindingsreeks.

  1. Selecteer in het Cloud Shell-venster aan de rechterkant van het scherm het pictogram Meer (...) en selecteer vervolgens Instellingen>ga naar klassieke versie.

  2. Voer de volgende opdracht uit, waarbij u <namespace-name> de Service Bus-naamruimte vervangt die u in de vorige oefening hebt gemaakt.

    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>
    

    De laatste regel in het antwoord is de verbindingsreeks, die het eindpunt voor uw naamruimte en de gedeelde toegangssleutel bevat. Deze moet er ongeveer uitzien als in het volgende voorbeeld:

    Endpoint=sb://example.servicebus.windows.net/;SharedAccessKeyName=RootManageSharedAccessKey;SharedAccessKey=xxxxxxxx
    
  3. Kopieer de verbindingsreeks vanuit Cloud Shell. U hebt deze verbindingsreeks meerdere keren in deze module nodig, zodat u deze mogelijk ergens bij de hand wilt opslaan.

De startertoepassing klonen en openen

Notitie

Voor het gemak geven de volgende taken u de opdracht om de verbindingsreeks in het Program.cs-bestand van beide consoletoepassingen in code te coderen. In een productietoepassing moet u een configuratiebestand of Azure Key Vault gebruiken om de verbindingsreeks op te slaan.

  1. Voer de volgende opdracht uit in Cloud Shell om de Git-projectoplossing te klonen:

    cd ~
    git clone https://github.com/MicrosoftDocs/mslearn-connect-services-together.git
    
  2. Voer de volgende opdracht uit om naar de startmap in uw gekloonde project te gaan en open de Cloud Shell-editor:

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

Code schrijven om een bericht naar een wachtrij te verzenden

  1. Open in de Cloud Shell-editor privatemessagesender/Program.cs en zoek de volgende coderegel:

    const string ServiceBusConnectionString = "";
    

    Plak de verbindingsreeks tussen de aanhalingstekens.

  2. Als u een andere naam dan salesmessages voor de wachtrijnaam hebt gebruikt, werkt u de waarde voor QueueName de eigenschap in de code bij:

    const string QueueName = "salesmessages";
    
  3. Als u het onderdeel wilt voltooien dat berichten over de verkoop verzendt, moet u een await operator toevoegen om de evaluatie van de asynchrone methode te onderbreken totdat de asynchrone bewerking is voltooid. Zoek de SendSalesMessageAsync() methode. Zoek in die methode de volgende coderegel:

    // Create a Service Bus client here
    

    Vervang die coderegel door de volgende 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. Zoek in de SendSalesMessageAsync() methode de volgende coderegel:

    // Create a sender here
    

    Vervang deze opmerking door de volgende code:

    await using ServiceBusSender sender = client.CreateSender(QueueName);
    
  5. Zoek in het try...catch blok de volgende coderegel:

    // Create and send a message here
    

    Vervang die coderegel door de volgende coderegels:

    string messageBody = $"$10,000 order for bicycle parts from retailer Adventure Works.";
    var message = new ServiceBusMessage(messageBody);
    
  6. Voeg de volgende code in op een nieuwe regel direct onder wat u zojuist hebt toegevoegd om het bericht weer te geven in de console:

    Console.WriteLine($"Sending message: {messageBody}");
    
  7. Voeg de volgende code in op de volgende regel:

    await sender.SendMessageAsync(message);
    
  8. Als u afzender- en clientobjecten wilt verwijderen, zoekt u aan het einde van het bestand de volgende opmerking:

    // Close the connection to the sender here
    

    Vervang die regel door de volgende 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. Controleer of uw laatste code voor privatemessagesender/Program.cs lijkt op het volgende voorbeeld:

    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. Selecteer Ctrl+S om uw wijzigingen op te slaan en selecteer vervolgens Ctrl+Q om de editor te sluiten.

Een bericht naar de wachtrij verzenden

  1. Voer in Cloud Shell de volgende opdracht uit om een bericht over een verkoop te verzenden. De eerste regel zorgt ervoor dat u zich in het juiste pad bevindt.

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

    Notitie

    De eerste keer dat u de apps in deze oefening uitvoert, kunt dotnet u pakketten uit externe bronnen herstellen en de apps bouwen.

    Terwijl het programma wordt uitgevoerd, worden berichten afgedrukt naar de console die aangeeft dat de app een bericht verzendt:

    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. Wanneer de app is voltooid, voert u de volgende opdracht uit, waarbij u <de naamruimtenaam vervangt door de naam van uw Service Bus-naamruimte> . Met deze opdracht wordt het aantal berichten in de wachtrij geretourneerd.

    az servicebus queue show \
        --resource-group "<rgn>[sandbox resource group name]</rgn>" \
        --name salesmessages \
        --query messageCount \
        --namespace-name <namespace-name>
    
  3. Voer de dotnet run opdracht opnieuw uit vanaf stap 1 en voer de servicebus queue show opdracht opnieuw uit. Telkens wanneer u de dotnet-app uitvoert, wordt er een nieuw bericht toegevoegd aan de wachtrij. U ziet de messageCount toename telkens wanneer u de Azure-opdracht uitvoert.

Schrijven van code voor het ontvangen van berichten van de wachtrij

  1. Voer de volgende opdracht uit om de editor opnieuw te openen:

    code .
    
  2. Open in de editor privatemessagereceiver/Program.cs en zoek de volgende coderegel:

    const string ServiceBusConnectionString = "";
    

    Plak tussen de aanhalingstekens de verbindingsreeks die u eerder hebt opgeslagen.

  3. Zoek de ReceiveSalesMessageAsync() methode. Zoek in die methode de volgende coderegel:

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

    Vervang die regel door de volgende code:

    var client = new ServiceBusClient(ServiceBusConnectionString);
    
  4. Als u opties voor berichtafhandeling wilt configureren, zoekt u de volgende regel code:

    // Create the options to use for configuring the processor
    

    Vervang deze regel door de volgende regels code:

    var processorOptions = new ServiceBusProcessorOptions
    {
        MaxConcurrentCalls = 1,
        AutoCompleteMessages = false
    };
    
  5. Als u een processor wilt maken, zoekt u de volgende coderegel:

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

    Vervang die regel door de volgende code:

    await using ServiceBusProcessor processor = client.CreateProcessor(QueueName, processorOptions);
    
  6. Als u de handlers wilt configureren, zoekt u de volgende coderegel:

    // Configure the message and error handler to use
    

    Vervang die regel door de volgende code:

    processor.ProcessMessageAsync += MessageHandler;
    processor.ProcessErrorAsync += ErrorHandler;
    
  7. Als u wilt beginnen met verwerken, zoekt u de volgende coderegel:

    // Start processing
    

    Vervang die regel door de volgende code:

    await processor.StartProcessingAsync();
    
  8. Als u de verbinding met Service Bus wilt sluiten, zoekt u de volgende coderegel:

    // Close the processor here
    

    Vervang die regel door de volgende code:

    await processor.CloseAsync();
    
  9. Code controleren in de 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. Code controleren in de 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. Controleer of uw laatste code voor privatemessagereceiver/Program.cs lijkt op het volgende voorbeeld:

    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. Selecteer Ctrl+S om uw wijzigingen op te slaan en selecteer vervolgens Ctrl+Q om de editor te sluiten.

Een bericht ontvangen uit de wachtrij

  1. Als u het onderdeel wilt uitvoeren dat een bericht ontvangt over een verkoop, voert u deze opdracht uit in Cloud Shell:

    dotnet run --project privatemessagereceiver
    
  2. Controleer de meldingen in Cloud Shell. Ga in Azure Portal naar uw Service Bus-naamruimte en controleer de berichtengrafiek:

    Received: $10,000 order for bicycle parts from retailer Adventure Works.
    
  3. Wanneer u ziet dat de berichten zijn ontvangen in de Cloud Shell, drukt u op Enter om de app te stoppen.

Het aantal berichten controleren

Voer de volgende code uit om te bevestigen dat alle berichten uit de wachtrij zijn verwijderd en vergeet niet om de naamruimtenaam te vervangen door <uw Service Bus-naamruimte> .

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

De uitvoer is 0 als alle berichten zijn verwijderd.

U hebt code geschreven waarmee een bericht over afzonderlijke verkopen naar een Service Bus-wachtrij wordt verzonden. In de gedistribueerde salesforce-toepassing moet u deze code schrijven in de mobiele app die verkoopmedewerkers op apparaten gebruiken.

U hebt ook code geschreven die een bericht van de Service Bus-wachtrij ontvangt. In de gedistribueerde salesforce-toepassing moet u deze code schrijven in de webservice die wordt uitgevoerd in Azure en ontvangen berichten verwerkt.