MSMQ-Aktivierung

Das MsmqActivation-Beispiel veranschaulicht, wie Anwendungen in windows Process Activation Service (WAS) gehostet werden, die aus einer Nachrichtenwarteschlange gelesen werden. In diesem Beispiel wird das netMsmqBinding verwendet und basiert auf dem Two-Way Kommunikationsbeispiel. In diesem Fall handelt es sich bei dem Dienst um eine im Internet gehostete Anwendung. Der Client ist selbst gehostet und gibt an die Konsole aus, um den Status eingereichter Bestellungen zu beobachten.

Hinweis

Die Einrichtungsverfahren und Build-Anweisungen für dieses Beispiel befinden sich am Ende dieses Themas.

Der Windows-Prozessaktivierungsdienst (WAS), der neue Prozessaktivierungsmechanismus für Windows Server 2008, stellt IIS-ähnliche Features bereit, die zuvor nur für HTTP-basierte Anwendungen für Anwendungen verfügbar waren, die nicht-HTTP-Protokolle verwenden. Windows Communication Foundation (WCF) verwendet die Listener-Adapterschnittstelle, um Aktivierungsanforderungen zu kommunizieren, die über die nicht-HTTP-Protokolle empfangen werden, die von WCF unterstützt werden, z. B. TCP, Named Pipes und MSMQ. Die Funktionalität für den Empfang von Anforderungen über Nicht-HTTP-Protokolle wird von verwalteten Windows-Diensten gehostet, die in SMSvcHost.exeausgeführt werden.

Der Net.Msmq Listener Adapter-Dienst (NetMsmqActivator) aktiviert anwendungen in der Warteschlange basierend auf Nachrichten in der Warteschlange.

Der Kunde sendet Bestellungen im Rahmen einer Transaktion an den Dienst. Der Dienst empfängt die Aufträge in einer Transaktion und verarbeitet sie. Der Dienst ruft dann den Client mit dem Status der Bestellung zurück. Zur Vereinfachung der bidirektionalen Kommunikation verwenden sowohl der Client als auch der Dienst Warteschlangen für Bestellungen und den Auftragsstatus.

Der IOrderProcessor-Dienstvertrag definiert die unidirektionalen Dienstvorgänge, die mit Warteschlangen funktionieren. Der Dienstvorgang verwendet den Antwortendpunkt, um Bestellstatus an den Client zu senden. Die Adresse des Antwortendpunkts ist die URL der Warteschlange, die verwendet wird, um den Auftragsstatus an den Client zu senden. Die Auftragsverarbeitungsanwendung implementiert diesen Vertrag.

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

Der Antwortvertrag, an den der Bestellstatus gesendet wird, wird vom Client angegeben. Der Kunde implementiert den Auftragsstatusvertrag. Der Dienst verwendet den generierten Client dieses Vertrags, um den Auftragsstatus an den Client zurückzusenden.

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

Der Dienstvorgang verarbeitet die übermittelte Bestellung. OperationBehaviorAttribute wird auf den Dienstvorgang angewendet, um die automatische Eintragung in die Transaktion, die für den Empfang der Nachricht aus der Warteschlange verwendet wird, und die automatische Fertigstellung der Transaktion bei Abschluss des Dienstvorgangs festzulegen. Die Orders Klasse kapselt die Bestellverarbeitungsfunktion. In diesem Fall wird die Bestellung zu einem Wörterbuch hinzugefügt. Die Transaktion, in der der Dienstvorgang aufgelistet ist, steht den Vorgängen in der Orders Klasse zur Verfügung.

Die Servicetätigkeit umfasst nicht nur die Bearbeitung der übermittelten Bestellung, sondern auch die Information des Kunden über den Auftragsstatus.

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

Die zu verwendende Clientbindung wird mithilfe einer Konfigurationsdatei angegeben.

Der MSMQ-Warteschlangenname wird in einem AppSettings-Abschnitt der Konfigurationsdatei angegeben. Der Endpunkt für den Dienst wird im Abschnitt "System.serviceModel" der Konfigurationsdatei definiert.

Hinweis

Der MSMQ-Warteschlangenname und die Endpunktadresse verwenden geringfügig unterschiedliche Adressierungskonventionen. Im MSQM-Warteschlangennamen wird ein Punkt (.) für den lokalen Computer verwendet, und in der Pfadangabe werden umgekehrte Schrägstriche als Trennzeichen verwendet. Die WCF-Endpunktadresse gibt ein net.msmq:-Schema an, verwendet "localhost" für den lokalen Computer und verwendet Schrägstriche in seinem Pfad. Um aus einer Warteschlange zu lesen, die auf dem Remotecomputer gehostet wird, ersetzen Sie "." und "localhost" durch den Namen des Remotecomputers.

Eine SVC-Datei mit dem Namen der Klasse wird verwendet, um den Dienstcode in WAS zu hosten.

Die Datei Service.svc selbst enthält eine Direktive zum Erstellen der OrderProcessorService.

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

Die Datei Service.svc enthält auch eine Assemblydirektive, um sicherzustellen, dass System.Transactions.dll geladen wird.

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

Der Client erstellt einen Transaktionsbereich. Die Kommunikation mit dem Dienst erfolgt im Rahmen der Transaktion, was dazu führt, dass sie als atome Einheit behandelt wird, bei der alle Nachrichten erfolgreich sind oder fehlschlagen. Für die Transaktion wird ein Commit ausgeführt, indem Complete im Geltungsbereich der Transaktion aufgerufen wird.

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

Der Clientcode implementiert den Vertrag, um den IOrderStatus Auftragsstatus vom Dienst zu erhalten. In diesem Fall wird der Bestellstatus ausgegeben.

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

Die Auftragsstatuswarteschlange wird in der Main Methode erstellt. Die Clientkonfiguration enthält die Auftragsstatusdienstkonfiguration zum Hosten des Auftragsstatusdiensts, wie in der folgenden Beispielkonfiguration gezeigt.

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

Wenn Sie das Beispiel ausführen, werden die Client- und Dienstaktivitäten sowohl in den Server- als auch in den Clientkonsolenfenstern angezeigt. Sie können sehen, dass der Server Nachrichten vom Client empfängt. Drücken Sie in jedem Konsolenfenster die EINGABETASTE, um den Server und den Client herunterzufahren.

Der Client zeigt die Vom Server gesendeten Bestellstatusinformationen an:

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

So können Sie das Beispiel einrichten, erstellen und ausführen

  1. Stellen Sie sicher, dass IIS 7.0 installiert ist, da sie für die WAS-Aktivierung erforderlich ist.

  2. Stellen Sie sicher, dass Sie das One-Time Setup-Verfahren für die Windows Communication Foundation-Beispieleausgeführt haben. Darüber hinaus müssen Sie die NICHT-HTTP-Aktivierungskomponenten des WCF installieren:

    1. Wählen Sie im Startmenü die Systemsteuerung aus.

    2. Wählen Sie "Programme und Features" aus.

    3. Klicken Sie auf "Windows-Features aktivieren oder deaktivieren".

    4. Klicken Sie unter "Zusammenfassung der Features" auf "Features hinzufügen".

    5. Erweitern Sie den Knoten Microsoft .NET Framework 3.0, und aktivieren Sie die Funktion Windows Communication Foundation-Nicht-HTTP-Aktivierung.

  3. Um die C#- oder Visual Basic .NET-Edition der Lösung zu erstellen, befolgen Sie die Anweisungen in Building the Windows Communication Foundation Samples.

  4. Führen Sie den Client aus, indem Sie client.exe in einem Befehlsfenster ausführen. Dadurch wird die Warteschlange erstellt und eine Nachricht an sie gesendet. Der Client verbleibt in der Ausführung, um das Ergebnis des Lesens der Nachricht durch den Dienst zu sehen.

  5. Der MSMQ-Aktivierungsdienst wird standardmäßig als Netzwerkdienst ausgeführt. Daher muss die Warteschlange, die zum Aktivieren der Anwendung verwendet wird, über Empfangs- und Vorschauberechtigungen für den Netzwerkdienst verfügen. Dies kann mithilfe von Message Queuing MMC hinzugefügt werden:

    1. Klicken Sie im Startmenü auf Ausführen, geben Sie Compmgmt.msc ein und drücken Sie die EINGABETASTE.

    2. Erweitern Sie unter Dienste und AnwendungenMessage Queuing.

    3. Klicken Sie auf "Private Warteschlangen".

    4. Klicken Sie mit der rechten Maustaste auf die Warteschlange (servicemodelsamples/Service.svc), und wählen Sie "Eigenschaften" aus.

    5. Klicken Sie auf der Registerkarte "Sicherheit" auf "Hinzufügen" und erteilen Sie dem Netzwerkdienst Lese- und Empfangsberechtigungen.

  6. Konfigurieren Sie den Windows Process Activation Service (WAS) zur Unterstützung der MSMQ-Aktivierung.

    Aus Gründen der Einfachheit werden die folgenden Schritte in einer Batchdatei implementiert, die namens AddMsmqSiteBinding.cmd im Beispielverzeichnis liegt.

    1. Zur Unterstützung der Net.msmq-Aktivierung muss die Standardwebsite zuerst an das net.msmq-Protokoll gebunden werden. Dies kann mithilfe von appcmd.exeerfolgen, die mit dem IIS 7.0-Verwaltungstoolset installiert wird. Führen Sie an einer Eingabeaufforderung auf höherer Ebene (Administrator) den folgenden Befehl aus.

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

      Hinweis

      Dieser Befehl ist eine einzelne Textzeile.

      Mit diesem Befehl wird der Standardwebsite eine net.msmq-Websitebindung hinzugefügt.

    2. Obwohl alle Anwendungen innerhalb einer Website eine gemeinsame net.msmq-Bindung verwenden, kann jede Anwendung die net.msmq-Unterstützung einzeln aktivieren. Um net.msmq für die Anwendung /servicemodelsamples zu aktivieren, führen Sie den folgenden Befehl in einer Eingabeaufforderung auf höherer Ebene (Administrator) aus.

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

      Hinweis

      Dieser Befehl ist eine einzelne Textzeile.

      Dieser Befehl ermöglicht den Zugriff auf die /servicemodelsamples-Anwendung mithilfe http://localhost/servicemodelsamples und net.msmq://localhost/servicemodelsamples.

  7. Wenn Sie dies noch nicht getan haben, stellen Sie sicher, dass der MSMQ-Aktivierungsdienst aktiviert ist. Klicken Sie im Startmenü auf „Ausführen“ und geben Sie Services.msc ein. Durchsuchen Sie die Liste der Dienste für den Net.Msmq Listener-Adapter. Klicken Sie mit der rechten Maustaste, und wählen Sie Eigenschaften aus. Legen Sie den Starttyp auf Automatisch fest, klicken Sie auf Übernehmen, und klicken Sie auf die Schaltfläche Start. Dieser Schritt darf nur einmal vor der ersten Verwendung des Net.Msmq Listener Adapter-Diensts ausgeführt werden.

  8. Führen Sie das Beispiel in einer Einzel- oder computerübergreifenden Konfiguration aus, indem Sie die Anweisungen unter Ausführen der Windows Communication Foundation-Beispiele befolgen. Ändern Sie außerdem den Code auf dem Client, der die Bestellung übermittelt, um den Computernamen in der URI der Warteschlange beim Übermitteln der Bestellung widerzuspiegeln. Verwenden Sie den folgenden Code:

    client.SubmitPurchaseOrder(po, "net.msmq://localhost/private/ServiceModelSamples/OrderStatus");
    
  9. Entfernen Sie die für dieses Beispiel hinzugefügte net.msmq-Websitebindung.

    Die folgenden Schritte werden in einer Batchdatei implementiert, die RemoveMsmqSiteBinding.cmd heißt und sich im Beispielverzeichnis befindet.

    1. Entfernen Sie net.msmq aus der Liste der aktivierten Protokolle, indem Sie den folgenden Befehl an einer Eingabeaufforderung mit erhöhten Rechten ausführen.

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

      Hinweis

      Dieser Befehl ist eine einzelne Textzeile.

    2. Entfernen Sie die net.msmq-Sitebindung, indem Sie den folgenden Befehl in einer Eingabeaufforderung auf höher Ebene ausführen.

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

      Hinweis

      Dieser Befehl ist eine einzelne Textzeile.

    Warnung

    Wenn Sie die Batchdatei ausführen, setzt dies den DefaultAppPool zurück, um ihn mit .NET Framework Version 2.0 auszuführen.

Standardmäßig wird mit der netMsmqBinding-Bindung die Transportsicherheit aktiviert. Zwei Eigenschaften MsmqAuthenticationMode und MsmqProtectionLevel, zusammen bestimmen den Typ der Transportsicherheit. Standardmäßig ist der Authentifizierungsmodus auf Windows und die Schutzebene auf .Sign Damit MSMQ die Authentifizierungs- und Signaturfunktion bereitstellt, muss sie Teil einer Domäne sein. Wenn Sie dieses Beispiel auf einem Computer ausführen, der nicht Teil einer Domäne ist, wird der folgende Fehler empfangen: "Das interne Nachrichtenwarteschlangenzertifikat des Benutzers ist nicht vorhanden".

So führen Sie das Beispiel auf einem Computer aus, der zu einer Arbeitsgruppe gehört

  1. Wenn Ihr Computer nicht Teil einer Domäne ist, deaktivieren Sie die Transportsicherheit, indem Sie den Authentifizierungsmodus und die Schutzstufe auf keine festlegen, wie in der folgenden Beispielkonfiguration gezeigt.

    <bindings>
        <netMsmqBinding>
            <binding configurationName="TransactedBinding">
                <security mode="None"/>
            </binding>
        </netMsmqBinding>
    </bindings>
    
  2. Ändern Sie die Konfiguration auf dem Server und dem Client, bevor Sie das Beispiel ausführen.

    Hinweis

    Die Einstellung von security mode zu None entspricht der Einstellung der Sicherheit von MsmqAuthenticationMode, MsmqProtectionLevel und Message zu None.

  3. Um die Aktivierung in einem Computer zu aktivieren, der einer Arbeitsgruppe beigetreten ist, müssen sowohl der Aktivierungsdienst als auch der Arbeitsprozess mit einem bestimmten Benutzerkonto ausgeführt werden (muss für beides identisch sein), und die Warteschlange muss ÜBER ACLs für das bestimmte Benutzerkonto verfügen.

    So ändern Sie die Identität, unter der der Arbeitsprozess ausgeführt wird:

    1. Führen Sie "Inetmgr.exe" aus.

    2. Klicken Sie unter Anwendungspools mit der rechten Maustaste auf den AppPool (in der Regel DefaultAppPool), und wählen Sie "Anwendungspoolstandard festlegen" aus.

    3. Ändern Sie die Identitätseigenschaften, um das bestimmte Benutzerkonto zu verwenden.

    So ändern Sie die Identität, unter der der Aktivierungsdienst ausgeführt wird:

    1. Führen Sie Services.msc aus.

    2. Klicken Sie mit der rechten Maustaste auf den Net.MsmqListener-Adapter, und wählen Sie "Eigenschaften" aus.

  4. Ändern Sie das Konto auf der Registerkarte "LogOn ".

  5. In der Arbeitsgruppe muss der Dienst auch mit einem uneingeschränkten Token ausgeführt werden. Führen Sie dazu folgendes in einem Befehlsfenster aus:

    sc sidtype netmsmqactivator unrestricted
    

Siehe auch