Dela via


MSMQ-aktivering

MsmqActivation-exemplet visar hur du kan hosta applikationer i Windows Process Activation Service (WAS) som läses från en meddelandekö. Det här exemplet använder netMsmqBinding och baseras på Two-Way Communication-exemplet . Tjänsten i det här fallet är ett webbaserat program och klienten är lokalt installerad och skriver ut till konsolen för att övervaka statusen av de inköpsorder som lämnats in.

Anmärkning

Installationsproceduren och bygginstruktionerna för det här exemplet finns i slutet av det här avsnittet.

Windows Process Activation Service (WAS), den nya processaktiveringsmekanismen för Windows Server 2008, tillhandahåller IIS-liknande funktioner som tidigare endast var tillgängliga för HTTP-baserade program för program som använder icke-HTTP-protokoll. Windows Communication Foundation (WCF) använder lyssnarkortgränssnittet för att kommunicera aktiveringsbegäranden som tas emot via de icke-HTTP-protokoll som stöds av WCF, till exempel TCP, Namngivna pipes och MSMQ. Funktionerna för att ta emot begäranden via icke-HTTP-protokoll hanteras av hanterade Windows-tjänster som körs i SMSvcHost.exe.

Tjänsten Net.Msmq Listener Adapter (NetMsmqActivator) aktiverar köade program baserat på meddelanden i kön.

Klienten skickar inköpsorder till tjänsten inom omfånget för en transaktion. Tjänsten tar emot beställningarna i en transaktion och bearbetar dem. Tjänsten anropar sedan klienten med status för ordern. För att underlätta dubbelriktad kommunikation använder både klienten och tjänsten köer för att ange inköpsorder och orderstatus.

Tjänstkontraktet IOrderProcessor definierar de enkelriktade tjänståtgärder som fungerar med köer. Tjänståtgärden använder svarsslutpunkten för att skicka orderstatusar till klienten. Svarsslutpunktens adress är URI:n för kön som används för att skicka orderstatusen tillbaka till klienten. Beställningsbearbetningsprogrammet implementerar det här kontraktet.

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

Svarskontraktet för att skicka orderstatus till anges av klienten. Klienten implementerar orderstatuskontraktet. Tjänsten använder den genererade klienten för det här kontraktet för att skicka orderstatusen tillbaka till klienten.

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

Servicefunktionen bearbetar den skickade inköpsordern. OperationBehaviorAttribute Tillämpas på tjänståtgärden för att ange automatisk registrering i transaktionen som används för att ta emot meddelandet från kön och automatiskt slutförande av transaktionen när tjänståtgärden har slutförts. Klassen Orders kapslar in funktioner för orderbearbetning. I det här fallet lägger den till inköpsordern i en ordlista. Den transaktion som tjänstoperationen är delaktig i är tillgänglig för operationerna i Orders klassen.

Tjänsten bearbetar den skickade inköpsordern och svarar dessutom tillbaka till klienten om status för ordern.

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();
        }
    }
}

Klientbindningen som ska användas anges med hjälp av en konfigurationsfil.

MSMQ-könamnet anges i avsnittet för appinställningar i konfigurationsfilen. Slutpunkten för tjänsten definieras i avsnittet System.serviceModel i konfigurationsfilen.

Anmärkning

MSMQ-könamnet och slutpunktsadressen använder lite olika adresseringskonventioner. MSMQ-könamnet använder en punkt (.) för den lokala datorn och omvänt snedstrecksavgränsare i sökvägen. WCF-slutpunktsadressen anger ett net.msmq:-schema, använder "localhost" för den lokala datorn och använder snedstreck i sökvägen. Om du vill läsa från en kö som finns på fjärrdatorn ersätter du "." och "localhost" till namnet på fjärrdatorn.

En .svc-fil med namnet på klassen används som värd för tjänstkoden i WAS.

Själva Filen Service.svc innehåller ett direktiv för att skapa OrderProcessorService.

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

Filen Service.svc innehåller också ett sammansättningsdirektiv för att säkerställa att System.Transactions.dll läses in.

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

Klienten skapar ett transaktionsomfång. Kommunikationen med tjänsten sker inom transaktionens omfång, vilket gör att den behandlas som en atomisk enhet där alla meddelanden lyckas eller misslyckas. Transaktionen slutförs genom att anropa Complete på transaktionsområdet.

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();
    }

Klientkoden implementerar IOrderStatus kontraktet för att ta emot orderstatus från tjänsten. I det här fallet skrivs orderstatusen ut.

[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);
    }
}

Orderstatuskön skapas i Main -metoden. Klientkonfigurationen inkluderar konfigurationen för att vara värd för orderstatustjänsten, som visas i följande exempelkonfiguration.

<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>

När du kör exemplet visas klient- och tjänstaktiviteterna i både server- och klientkonsolfönstren. Du kan se att servern tar emot meddelanden från klienten. Tryck på RETUR i varje konsolfönster för att stänga av servern och klienten.

Klienten visar orderstatusinformationen som skickas av servern:

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

Så här konfigurerar du, skapar och kör exemplet

  1. Kontrollera att IIS 7.0 är installerat eftersom det krävs för WAS-aktivering.

  2. Kontrollera att du har utfört One-Time installationsproceduren för Windows Communication Foundation-exempel. Dessutom måste du installera WCF-komponenter för icke-HTTP-aktivering.

    1. Start-menyn väljer du Kontrollpanelen.

    2. Välj Program och funktioner.

    3. Klicka på Aktivera eller inaktivera Windows-funktioner.

    4. Under Funktionssammanfattning klickar du på Lägg till funktioner.

    5. Expandera Microsoft .NET Framework 3.0-noden och markera funktionen Windows Communication Foundation Non-HTTP Activation.

  3. Om du vill skapa C# eller Visual Basic .NET-versionen av lösningen följer du anvisningarna i Skapa Windows Communication Foundation-exempel.

  4. Kör klienten genom att köra client.exe från ett kommandofönster. Då skapas kön och ett meddelande skickas till den. Låt klienten köras för att se resultatet av att tjänsten läser meddelandet

  5. MSMQ-aktiveringstjänsten körs som nätverkstjänst som standard. Därför måste kön som används för att aktivera programmet ha behörighet att ta emot och granska för nätverkstjänsten. Detta kan läggas till med hjälp av MMC för meddelandeköer:

    1. Start-menyn klickar du på Kör, skriver Compmgmt.msc och trycker på RETUR.

    2. Under Tjänster och program expanderar du Meddelandeköer.

    3. Klicka på Privata köer.

    4. Högerklicka på kön (servicemodelsamples/Service.svc) och välj Egenskaper.

    5. På fliken Säkerhet klickar du på Lägg till och ger en titt och tar emot behörigheter till Nätverkstjänsten.

  6. Konfigurera Windows Process Activation Service (WAS) för att stödja MSMQ-aktivering.

    Som en bekvämlighet implementeras följande steg i en batchfil med namnet AddMsmqSiteBinding.cmd som finns i exempelkatalogen.

    1. För att stödja net.msmq-aktivering måste standardwebbplatsen först vara bunden till net.msmq-protokollet. Detta kan göras med hjälp av appcmd.exe, som installeras med IIS 7.0-hanteringsverktygen. Kör följande kommando från en kommandotolk med administratörsrättigheter.

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

      Anmärkning

      Det här kommandot är en enda textrad.

      Det här kommandot lägger till en net.msmq-platsbindning till standardwebbplatsen.

    2. Även om alla program på en webbplats delar en gemensam net.msmq-bindning kan varje program aktivera net.msmq-stöd individuellt. Om du vill aktivera net.msmq för programmet /servicemodelsamples kör du följande kommando från en kommandotolk med administratörsbehörighet.

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

      Anmärkning

      Det här kommandot är en enda textrad.

      Med det här kommandot kan programmet /servicemodelsamples användas med hjälp av http://localhost/servicemodelsamples och net.msmq://localhost/servicemodelsamples.

  7. Om du inte har gjort det tidigare kontrollerar du att MSMQ-aktiveringstjänsten är aktiverad. På Start-menyn klickar du på Kör och skriver Services.msc. Sök i listan över tjänster efter Net.Msmq-lyssnaradaptern. Högerklicka och välj Egenskaper. Ange Starttyp till Automatisk, klicka på Använd och klicka på startknappen . Det här steget får bara utföras en gång före den första användningen av tjänsten Net.Msmq Listener Adapter.

  8. Om du vill köra exemplet i en konfiguration med en eller flera datorer följer du anvisningarna i Köra Windows Communication Foundation-exempel. Ändra dessutom koden på den klient som sänder inköpsordern så att den inkluderar datornamnet i URI för kön när du skickar inköpsordern. Använd följande kod:

    client.SubmitPurchaseOrder(po, "net.msmq://localhost/private/ServiceModelSamples/OrderStatus");
    
  9. Ta bort net.msmq-platsbindningen som du lade till för det här exemplet.

    Som en bekvämlighet implementeras följande steg i en batchfil med namnet RemoveMsmqSiteBinding.cmd som finns i exempelkatalogen:

    1. Ta bort net.msmq från listan över aktiverade protokoll genom att köra följande kommando från en upphöjd kommandotolk.

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

      Anmärkning

      Det här kommandot är en enda textrad.

    2. Ta bort net.msmq-platsbindningen genom att köra följande kommando från en förhöjd kommandotolk.

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

      Anmärkning

      Det här kommandot är en enda textrad.

    Varning

    Om du kör batchfilen återställs DefaultAppPool så att den körs med .NET Framework version 2.0.

Som standard är säkerheten aktiverad med transportbindningen netMsmqBinding. Två egenskaper, MsmqAuthenticationMode och MsmqProtectionLevel, bestämmer tillsammans typen av transportsäkerhet. Som standard är autentiseringsläget inställt på Windows och skyddsnivån är inställd på Sign. För att MSMQ ska kunna tillhandahålla autentiserings- och signeringsfunktionen måste den vara en del av en domän. Om du kör det här exemplet på en dator som inte ingår i en domän tas följande fel emot: "Användarens interna meddelandeköcertifikat finns inte".

Så här kör du exemplet på en dator som är ansluten till en arbetsgrupp

  1. Om datorn inte är en del av en domän inaktiverar du transportsäkerheten genom att ställa in autentiseringsläget och skyddsnivån på ingen som visas i följande exempelkonfiguration.

    <bindings>
        <netMsmqBinding>
            <binding configurationName="TransactedBinding">
                <security mode="None"/>
            </binding>
        </netMsmqBinding>
    </bindings>
    
  2. Ändra konfigurationen på både servern och klienten innan du kör exemplet.

    Anmärkning

    Inställning av security mode till None motsvarar inställning av MsmqAuthenticationMode, MsmqProtectionLevel och Message säkerhet till None.

  3. För att aktivera aktivering i en dator som är ansluten till en arbetsgrupp måste både aktiveringstjänsten och arbetsprocessen köras med ett specifikt användarkonto (måste vara samma för båda) och kön måste ha ACL:er för det specifika användarkontot.

    Så här ändrar du den identitet som arbetsprocessen körs under:

    1. Kör Inetmgr.exe.

    2. Under Programpooler högerklickar du på AppPool (vanligtvis DefaultAppPool) och väljer Ange standardinställningar för programpool....

    3. Ändra identitetsegenskaperna så att det specifika användarkontot används.

    Så här ändrar du den identitet som aktiveringstjänsten körs under:

    1. Kör programmet Services.msc.

    2. Högerklicka på Net.MsmqListener-adaptern och välj Egenskaper.

  4. Ändra kontot på fliken LogOn .

  5. I arbetsgrupp måste tjänsten också köras med en obegränsad token. Det gör du genom att köra följande i ett kommandofönster:

    sc sidtype netmsmqactivator unrestricted
    

Se även