Delen via


MSMQ-activering

In het msmqActivation-voorbeeld ziet u hoe u toepassingen host in Windows Process Activation Service (WAS) die worden gelezen uit een berichtenwachtrij. In dit voorbeeld wordt gebruikgemaakt van de netMsmqBinding en is gebaseerd op het voorbeeld van tweerichtingscommunicatie . De service in dit geval is een web-hostende toepassing en de client wordt zelf-hostend en wordt uitgevoerd naar de console om de status van de ingediende inkooporders te observeren.

Notitie

De installatieprocedure en build-instructies voor dit voorbeeld bevinden zich aan het einde van dit onderwerp.

Windows Process Activation Service (WAS), het nieuwe procesactiveringsmechanisme voor Windows Server 2008, biedt IIS-achtige functies die eerder alleen beschikbaar waren voor HTTP-toepassingen voor toepassingen die gebruikmaken van niet-HTTP-protocollen. Windows Communication Foundation (WCF) maakt gebruik van de listeneradapterinterface om activeringsaanvragen te communiceren die worden ontvangen via de niet-HTTP-protocollen die worden ondersteund door WCF, zoals TCP, Named Pipes en MSMQ. De functionaliteit voor het ontvangen van aanvragen via niet-HTTP-protocollen wordt gehost door beheerde Windows-services die worden uitgevoerd in SMSvcHost.exe.

De Net.Msmq Listener Adapter-service (NetMsmqActivator) activeert toepassingen in de wachtrij op basis van berichten in de wachtrij.

De client verzendt inkooporders naar de service vanuit het bereik van een transactie. De service ontvangt de orders in een transactie en verwerkt deze. De service roept vervolgens de client terug met de status van de order. Om communicatie in twee richtingen te vergemakkelijken, gebruiken de client en service wachtrijen om inkooporders en orderstatus in de wachtrij te plaatsen.

Het servicecontract IOrderProcessor definieert de éénrichtingsservicebewerkingen die werken met wachtrijen. De servicebewerking maakt gebruik van het antwoordeindpunt om orderstatussen naar de client te verzenden. Het adres van het antwoordeindpunt is de URI van de wachtrij die wordt gebruikt om de orderstatus terug te sturen naar de client. De orderverwerkingstoepassing implementeert dit contract.

[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]
public interface IOrderProcessor
{
    [OperationContract(IsOneWay = true)]
    void SubmitPurchaseOrder(PurchaseOrder po,
                                           string reportOrderStatusTo);
}

Het antwoordcontract waaraan de orderstatus moet worden verzonden, wordt door de client opgegeven. De client implementeert het orderstatuscontract. De service gebruikt de gegenereerde client van dit contract om de orderstatus terug te sturen naar de client.

[ServiceContract]
public interface IOrderStatus
{
    [OperationContract(IsOneWay = true)]
    void OrderStatus(string poNumber, string status);
}

De servicebewerking verwerkt de ingediende inkooporder. De OperationBehaviorAttribute bewerking wordt toegepast op de servicebewerking om automatische opname in de transactie op te geven die wordt gebruikt voor het ontvangen van het bericht uit de wachtrij en automatische voltooiing van de transactie bij voltooiing van de servicebewerking. De Orders klasse bevat functionaliteit voor orderverwerking. In dit geval wordt de inkooporder toegevoegd aan een woordenlijst. De transactie waarin de servicebewerking is opgenomen, is beschikbaar voor de bewerkingen in de Orders klasse.

De servicebewerking, naast het verwerken van de ingediende inkooporder, reageert terug naar de client over de status van de order.

public class OrderProcessorService : IOrderProcessor
{
    [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
    public void SubmitPurchaseOrder(PurchaseOrder po, string reportOrderStatusTo)
    {
        Orders.Add(po);
        Console.WriteLine("Processing {0} ", po);
        Console.WriteLine("Sending back order status information");
        NetMsmqBinding msmqCallbackBinding = new NetMsmqBinding();
        msmqCallbackBinding.Security.Mode = NetMsmqSecurityMode.None;
        OrderStatusClient client = new OrderStatusClient(msmqCallbackBinding, new EndpointAddress(reportOrderStatusTo));
        // please note that the same transaction that is used to dequeue purchase order is used
        // to send back order status
        using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
        {
            client.OrderStatus(po.PONumber, po.Status);
            scope.Complete();
        }
    }
}

De te gebruiken clientbinding wordt opgegeven met behulp van een configuratiebestand.

De naam van de MSMQ-wachtrij wordt opgegeven in een app Instellingen sectie van het configuratiebestand. Het eindpunt voor de service wordt gedefinieerd in de sectie System.serviceModel van het configuratiebestand.

Notitie

De MSMQ-wachtrijnaam en het eindpuntadres gebruiken iets andere adresseringsconventies. De naam van de MSMQ-wachtrij maakt gebruik van een punt (.) voor de lokale computer en backslashscheidingstekens in het pad. Het WCF-eindpuntadres specificeert een net.msmq: schema, gebruikt 'localhost' voor de lokale computer en maakt gebruik van slashes in het pad. Als u wilt lezen uit een wachtrij die wordt gehost op de externe computer, vervangt u de naam '. en 'localhost' in de naam van de externe computer.

Een .svc-bestand met de naam van de klasse wordt gebruikt om de servicecode in WAS te hosten.

Het Bestand Service.svc zelf bevat een instructie om het OrderProcessorServicete maken.

<%@ServiceHost language="c#" Debug="true" Service="Microsoft.ServiceModel.Samples.OrderProcessorService"%>

Het bestand Service.svc bevat ook een assembly-instructie om ervoor te zorgen dat System.Transactions.dll wordt geladen.

<%@Assembly name="System.Transactions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"%>

De client maakt een transactiebereik. Communicatie met de service vindt plaats binnen het bereik van de transactie, waardoor deze wordt behandeld als een atomische eenheid waar alle berichten slagen of mislukken. De transactie wordt doorgevoerd door het aanroepen van Complete het transactiebereik.

using (ServiceHost serviceHost = new ServiceHost(typeof(OrderStatusService)))
{
    // Open the ServiceHostBase to create listeners and start listening
    // for order status messages.
    serviceHost.Open();

    // Create a proxy with given client endpoint configuration
    OrderProcessorClient client = new OrderProcessorClient();

    // Create the purchase order
    PurchaseOrder po = new PurchaseOrder();
    po.CustomerId = "somecustomer.com";
    po.PONumber = Guid.NewGuid().ToString();

    PurchaseOrderLineItem lineItem1 = new PurchaseOrderLineItem();
    lineItem1.ProductId = "Blue Widget";
    lineItem1.Quantity = 54;
    lineItem1.UnitCost = 29.99F;

    PurchaseOrderLineItem lineItem2 = new PurchaseOrderLineItem();
    lineItem2.ProductId = "Red Widget";
    lineItem2.Quantity = 890;
    lineItem2.UnitCost = 45.89F;

    po.orderLineItems = new PurchaseOrderLineItem[2];
    po.orderLineItems[0] = lineItem1;
    po.orderLineItems[1] = lineItem2;

    //Create a transaction scope.
    using (TransactionScope scope = new
        TransactionScope(TransactionScopeOption.Required))
    {
        // Make a queued call to submit the purchase order
        client.SubmitPurchaseOrder(po,
       "net.msmq://localhost/private/ServiceModelSamplesOrder/OrderStatus");
        // Complete the transaction.
        scope.Complete();
    }

    //Closing the client gracefully closes the connection and cleans up
    //resources
    client.Close();

    Console.WriteLine();
    Console.WriteLine("Press <ENTER> to terminate client.");
    Console.ReadLine();

    // Close the ServiceHostBase to shutdown the service.
    serviceHost.Close();
    }

De clientcode implementeert het IOrderStatus contract om de orderstatus van de service te ontvangen. In dit geval wordt de orderstatus afgedrukt.

[ServiceBehavior]
public class OrderStatusService : IOrderStatus
{
    [OperationBehavior(TransactionAutoComplete = true,
                        TransactionScopeRequired = true)]
    public void OrderStatus(string poNumber, string status)
    {
        Console.WriteLine("Status of order {0}:{1} ",
                                         poNumber , status);
    }
}

De orderstatuswachtrij wordt gemaakt in de Main methode. De clientconfiguratie bevat de configuratie van de orderstatusservice voor het hosten van de orderstatusservice, zoals wordt weergegeven in de volgende voorbeeldconfiguratie.

<appSettings>
    <!-- use appSetting to configure MSMQ queue name -->
    <add key="targetQueueName" value=".\private$\ServiceModelSamples/service.svc" />
    <add key="responseQueueName" value=".\private$\ServiceModelSamples/OrderStatus" />
  </appSettings>

<system.serviceModel>

    <services>
      <service
         name="Microsoft.ServiceModel.Samples.OrderStatusService">
        <!-- Define NetMsmqEndpoint -->
        <endpoint address="net.msmq://localhost/private/ServiceModelSamples/OrderStatus"
                  binding="netMsmqBinding"
                  contract="Microsoft.ServiceModel.Samples.IOrderStatus" />
      </service>
    </services>

    <client>
      <!-- Define NetMsmqEndpoint -->
      <endpoint name="OrderProcessorEndpoint"
                address="net.msmq://localhost/private/ServiceModelSamples/service.svc"
                binding="netMsmqBinding"
                contract="Microsoft.ServiceModel.Samples.IOrderProcessor" />
    </client>

  </system.serviceModel>

Wanneer u het voorbeeld uitvoert, worden de client- en serviceactiviteiten weergegeven in zowel de server- als clientconsolevensters. U kunt zien dat de server berichten ontvangt van de client. Druk in elk consolevenster op Enter om de server en client af te sluiten.

De client geeft de orderstatusgegevens weer die door de server zijn verzonden:

Press <ENTER> to terminate client.
Status of order 70cf9d63-3dfa-4e69-81c2-23aa4478ebed :Pending

Het voorbeeld instellen, compileren en uitvoeren

  1. Zorg ervoor dat IIS 7.0 is geïnstalleerd, omdat deze is vereist voor WAS-activering.

  2. Zorg ervoor dat u de eenmalige installatieprocedure voor de Windows Communication Foundation-voorbeelden hebt uitgevoerd. Daarnaast moet u de WCF niet-HTTP-activeringsonderdelen installeren:

    1. Kies Configuratiescherm in het menu Start.

    2. Selecteer Programma's en onderdelen.

    3. Klik op Windows-onderdelen in- of uitschakelen.

    4. Klik onder Functiesoverzicht op Onderdelen toevoegen.

    5. Vouw het knooppunt Microsoft .NET Framework 3.0 uit en controleer de functie Niet-HTTP-activering van Windows Communication Foundation.

  3. Als u de C# of Visual Basic .NET-editie van de oplossing wilt bouwen, volgt u de instructies in het bouwen van de Windows Communication Foundation-voorbeelden.

  4. Voer de client uit door client.exe uit te voeren vanuit een opdrachtvenster. Hiermee wordt de wachtrij gemaakt en wordt er een bericht naar verzonden. Laat de client actief om het resultaat te zien van de service die het bericht leest

  5. De MSMQ-activeringsservice wordt standaard uitgevoerd als Netwerkservice. Daarom moet de wachtrij die wordt gebruikt om de toepassing te activeren, machtigingen voor ontvangen en bekijken hebben voor Netwerkservice. Dit kan worden toegevoegd met behulp van message queuing MMC:

    1. Klik in het menu Start op Uitvoeren en typ Compmgmt.msc en druk op Enter.

    2. Vouw onder Services en toepassingen Message Queuing uit.

    3. Klik op Privéwachtrijen.

    4. Klik met de rechtermuisknop op de wachtrij (servicemodelsamples/Service.svc) en kies Eigenschappen.

    5. Klik op het tabblad Beveiliging op Toevoegen en geef een korte weergave en ontvang machtigingen voor De netwerkservice.

  6. Configureer de Windows Process Activation Service (WAS) ter ondersteuning van MSMQ-activering.

    Als u wilt, worden de volgende stappen geïmplementeerd in een batchbestand met de naam AddMsmqSiteBinding.cmd zich in de voorbeeldmap bevindt.

    1. Ter ondersteuning van net.msmq-activering moet de standaardwebsite eerst zijn gebonden aan het net.msmq-protocol. U kunt dit doen met behulp van appcmd.exe, die is geïnstalleerd met de IIS 7.0-beheerhulpprogramma'sset. Voer vanaf een opdrachtprompt met verhoogde bevoegdheid (administrator) de volgende opdracht uit.

      %windir%\system32\inetsrv\appcmd.exe set site "Default Web Site"
      -+bindings.[protocol='net.msmq',bindingInformation='localhost']
      

      Notitie

      Deze opdracht is één regel tekst.

      Met deze opdracht wordt een net.msmq-sitebinding toegevoegd aan de standaardwebsite.

    2. Hoewel alle toepassingen binnen een site een algemene net.msmq-binding delen, kan elke toepassing ondersteuning voor net.msmq afzonderlijk inschakelen. Als u net.msmq wilt inschakelen voor de toepassing /servicemodelsamples, voert u de volgende opdracht uit vanaf een opdrachtprompt met verhoogde bevoegdheid.

      %windir%\system32\inetsrv\appcmd.exe set app "Default Web Site/servicemodelsamples" /enabledProtocols:http,net.msmq
      

      Notitie

      Deze opdracht is één regel tekst.

      Met deze opdracht kan de toepassing /servicemodelsamples worden geopend met behulp van http://localhost/servicemodelsamples en net.msmq://localhost/servicemodelsamples.

  7. Als u dit nog niet eerder hebt gedaan, moet u ervoor zorgen dat de MSMQ-activeringsservice is ingeschakeld. Klik in het menu Start op Uitvoeren en typ Services.msc. Zoek in de lijst met services voor de Net.Msmq Listener Adapter. Klik met de rechtermuisknop en selecteer Eigenschappen. Stel het opstarttype in op Automatisch, klik op Toepassen en klik op de knop Start . Deze stap moet slechts eenmaal vóór het eerste gebruik van de Net.Msmq Listener Adapter-service worden uitgevoerd.

  8. Als u het voorbeeld wilt uitvoeren in een configuratie van één of meerdere computers, volgt u de instructies in Het uitvoeren van de Windows Communication Foundation-voorbeelden. Wijzig bovendien de code op de client die de inkooporder indient om de computernaam in de URI van de wachtrij weer te geven bij het indienen van de inkooporder. Gebruik de volgende code:

    client.SubmitPurchaseOrder(po, "net.msmq://localhost/private/ServiceModelSamples/OrderStatus");
    
  9. Verwijder de net.msmq-sitebinding die u voor dit voorbeeld hebt toegevoegd.

    Voor het gemak worden de volgende stappen geïmplementeerd in een batchbestand met de naam RemoveMsmqSiteBinding.cmd zich in de voorbeeldmap bevindt:

    1. Verwijder net.msmq uit de lijst met ingeschakelde protocollen door de volgende opdracht uit te voeren vanaf een opdrachtprompt met verhoogde bevoegdheid.

      %windir%\system32\inetsrv\appcmd.exe set app "Default Web Site/servicemodelsamples" /enabledProtocols:http
      

      Notitie

      Deze opdracht is één regel tekst.

    2. Verwijder de sitebinding net.msmq door de volgende opdracht uit te voeren vanaf een opdrachtprompt met verhoogde bevoegdheid.

      %windir%\system32\inetsrv\appcmd.exe set site "Default Web Site" --bindings.[protocol='net.msmq',bindingInformation='localhost']
      

      Notitie

      Deze opdracht is één regel tekst.

    Waarschuwing

    Als u het batchbestand uitvoert, wordt de DefaultAppPool opnieuw ingesteld voor uitvoering met .NET Framework versie 2.0.

Standaard is beveiliging ingeschakeld bij het netMsmqBinding bindingstransport. Twee eigenschappen, MsmqAuthenticationMode en MsmqProtectionLevelsamen bepalen het type transportbeveiliging. De verificatiemodus is standaard ingesteld op Windows en het beveiligingsniveau is ingesteld op Sign. MsMQ moet deel uitmaken van een domein om de verificatie- en ondertekeningsfunctie op te geven. Als u dit voorbeeld uitvoert op een computer die geen deel uitmaakt van een domein, wordt de volgende fout ontvangen: 'Het interne berichtwachtrijcertificaat van de gebruiker bestaat niet'.

Het voorbeeld uitvoeren op een computer die is gekoppeld aan een werkgroep

  1. Als uw computer geen deel uitmaakt van een domein, schakelt u transportbeveiliging uit door de verificatiemodus en het beveiligingsniveau in te stellen op geen, zoals wordt weergegeven in de volgende voorbeeldconfiguratie.

    <bindings>
        <netMsmqBinding>
            <binding configurationName="TransactedBinding">
                <security mode="None"/>
            </binding>
        </netMsmqBinding>
    </bindings>
    
  2. Wijzig de configuratie op zowel de server als de client voordat u het voorbeeld uitvoert.

    Notitie

    Instelling security mode is None gelijk aan instelling MsmqAuthenticationModeen MsmqProtectionLevelMessage beveiliging op None.

  3. Als u activering wilt inschakelen op een computer die is gekoppeld aan een werkgroep, moeten zowel de activeringsservice als het werkproces worden uitgevoerd met een specifiek gebruikersaccount (moet hetzelfde zijn voor beide) en moet de wachtrij ACL's hebben voor het specifieke gebruikersaccount.

    Ga als volgende te werk om de identiteit te wijzigen waaronder het werkproces wordt uitgevoerd:

    1. Voer Inetmgr.exe uit.

    2. Klik onder Toepassingsgroepen met de rechtermuisknop op de AppPool (meestal DefaultAppPool) en kies Standaardinstellingen voor groep van toepassingen instellen....

    3. Wijzig de identiteitseigenschappen om het specifieke gebruikersaccount te gebruiken.

    Ga als volgende te werk om de identiteit te wijzigen die door de activeringsservice wordt uitgevoerd:

    1. Voer Services.msc uit.

    2. Klik met de rechtermuisknop op de Net.MsmqListener-adapter en kies Eigenschappen.

  4. Wijzig het account op het tabblad LogOn .

  5. In werkgroep moet de service ook worden uitgevoerd met behulp van een onbeperkt token. Voer hiervoor het volgende uit in een opdrachtvenster:

    sc sidtype netmsmqactivator unrestricted
    

Zie ook