Bidirektionale KommunikationTwo-Way Communication

Dieses Beispiel veranschaulicht das Ausführen der transaktiven bidirektionalen Warteschlangenkommunikation über MSMQ.This sample demonstrates how to perform transacted two-way queued communication over MSMQ. In diesem Beispiel wird die netMsmqBinding-Bindung verwendet.This sample uses the netMsmqBinding binding. Der Dienst ist in diesem Fall eine selbst gehostete Konsolenanwendung, die es Ihnen ermöglicht, den Dienst beim Empfang von Nachrichten in der Warteschlange zu beobachten.In this case, the service is a self-hosted console application that allows you to observe the service receiving queued messages.

Hinweis

Die Setupprozedur und die Buildanweisungen für dieses Beispiel befinden sich am Ende dieses Themas.The setup procedure and build instructions for this sample are located at the end of this topic.

Dieses Beispiel basiert auf der Binden von MSMQ transaktive.This sample is based on the Transacted MSMQ Binding.

In einer Warteschlangenkommunikation kommuniziert der Client über eine Warteschlange mit dem Dienst.In queued communication, the client communicates to the service using a queue. Der Client sendet Nachrichten an eine Warteschlange, und der Dienst empfängt Nachrichten von der Warteschlange.The client sends messages to a queue, and the service receives messages from the queue. Folglich müssen der Dienst und der Client nicht gleichzeitig ausgeführt werden, um über eine Warteschlange zu kommunizieren.The service and client therefore, do not have to be running at the same time to communicate using a queue.

In diesem Beispiel wird die bidirektionale Kommunikation mit Warteschlangen veranschaulicht.This sample demonstrates 2-way communication using queues. Der Client sendet Bestellungen aus dem Bereich einer Transaktion an die Warteschlange.The client sends purchase orders to the queue from within the scope of a transaction. Der Dienst empfängt die Bestellungen, verarbeitet die Bestellungen und meldet an den Client den Status der Bestellung aus der Warteschlange innerhalb des Bereichs der Transaktion.The service receives the orders, processes the order and then calls back the client with the status of the order from the queue within the scope of a transaction. Zur Vereinfachung der bidirektionalen Kommunikation verwenden sowohl der Client als auch der Dienst Warteschlangen für Bestellungen und den Auftragsstatus.To facilitate two-way communication the client and service both use queues to enqueue purchase orders and order status.

Der IOrderProcessor-Dienstvertrag definiert einen unidirektionalen Dienstvorgang, der für die Verwendung mit Warteschlangen geeignet ist.The service contract IOrderProcessor defines one-way service operations that suit the use of queuing. Der Dienstvorgang beinhaltet den Antwortendpunkt, an den der Auftragsstatus gesendet wird.The service operation includes the reply endpoint to use to send the order statuses to. Der Antwortendpunkt ist der URI der Warteschlange für die Rücksendung des Auftragsstatus an den Client.The reply endpoint is the URI of the queue to send the order status back to the client. Die Anwendung für die Auftragsverarbeitung implementiert diesen Vertrag.The order processing application implements this contract.

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

Der Antwortvertrag für die Sendung des Auftragsstatus wird vom Client angegeben.The reply contract to send order status is specified by the client. Der Client implementiert den Auftragsstatusvertrag.The client implements the order status contract. Der Dienst verwendet den generierten Proxy dieses Vertrags, um den Auftragsstatus an den Client zurückzusenden.The service uses the generated proxy of this contract to send order status back to the client.

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

Der Dienstvorgang verarbeitet die übermittelte Bestellung.The service operation processes the submitted purchase order. Das OperationBehaviorAttribute wird auf den Dienstvorgang angewendet, um die automatische Eintragung für eine Transaktion festzulegen, die für den Empfang der Nachricht aus der Warteschlange verwendet wird, und für die automatische Fertigstellung von Transaktionen, wenn der Dienstvorgang fertig gestellt wird.The OperationBehaviorAttribute is applied to the service operation to specify automatic enlistment in a transaction that is used to receive the message from the queue and automatic completion of transactions on completion of the service operation. Die Orders-Klasse kapselt die Auftragsverarbeitungsfunktion.The Orders class encapsulates order processing functionality. In diesem Fall fügt sie die Bestellung einem Wörterbuch hinzu.In this case, it adds the purchase order to a dictionary. Die Transaktion, in der der Dienstvorgang eingetragen wurde, steht den Vorgängen in der Orders-Klasse zur Verfügung.The transaction that the service operation enlisted in is available to the operations in the Orders class.

Der Dienstvorgang verarbeitet die übermittelte Bestellung und meldet dem Client den Status des Auftrags.The service operation, in addition to processing the submitted purchase order, replies back to the client on the status of the order.

[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("ClientCallbackBinding");  
    OrderStatusClient client = new OrderStatusClient(msmqCallbackBinding, new EndpointAddress(reportOrderStatusTo));  

    // Please note that the same transaction that is used to dequeue the purchase order is used  
    // to send back order status.  
    using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))  
    {  
        client.OrderStatus(po.PONumber, po.Status);  
        scope.Complete();  
    }  
    //Close the client.  
    client.Close();  
}  

Der MSMQ-Warteschlangenname wird im appSettings-Abschnitt der Konfigurationsdatei angegeben.The MSMQ queue name is specified in an appSettings section of the configuration file. Der Endpunkt für den Dienst wird im Abschnitt System.ServiceModel der Konfigurationsdatei definiert.The endpoint for the service is defined in the System.ServiceModel section of the configuration file.

Hinweis

Der Name der MSMQ-Warteschlange und die Endpunktadresse verwenden geringfügig abweichende Adressierungskonventionen.The MSMQ queue name and endpoint address use slightly different addressing conventions. Im MSMQ-Warteschlangennamen wird ein Punkt (.) für den lokalen Computer verwendet, und in der Pfadangabe werden umgekehrte Schrägstriche als Trennzeichen verwendet.The MSMQ queue name uses a dot (.) for the local machine and backslash separators in its path. Die Windows Communication Foundation (WCF)Windows Communication Foundation (WCF)-Endpunktadresse gibt ein net.msmq:-Schema an und verwendet "localhost" als lokalen Computer sowie Schrägstriche im Pfad.The Windows Communication Foundation (WCF)Windows Communication Foundation (WCF) endpoint address specifies a net.msmq: scheme, uses "localhost" for the local machine, and uses forward slashes in its path. Um in einer Warteschlange zu lesen, die auf einem Remotecomputer gehostet wird, ersetzen Sie "." und "localhost" durch den Namen des Remotecomputers.To read from a queue that is hosted on the remote machine, replace the "." and "localhost" to the remote machine name.

Der Dienst ist selbst gehostet.The service is self hosted. Bei Verwendung des MSMQ-Transports muss die Warteschlange im Voraus erstellt werden.When using the MSMQ transport, the queue used must be created in advance. Dies kann manuell erfolgen oder mithilfe eines Codes.This can be done manually or through code. In diesem Beispiel prüft der Dienst, ob die Warteschlange vorhanden ist, und erstellt sie gegebenenfalls.In this sample, the service checks for the existence of the queue and creates it, if necessary. Der Warteschlangenname wird aus der Konfigurationsdatei gelesen.The queue name is read from the configuration file. Die Basisadresse wird verwendet, durch die ServiceModel Metadata Utility Tool (Svcutil.exe) auf den Proxy an den Dienst zu generieren.The base address is used by the ServiceModel Metadata Utility Tool (Svcutil.exe) to generate the proxy to the service.

// Host the service within this EXE console application.  
public static void Main()  
{  
    // Get MSMQ queue name from appSettings in configuration.  
    string queueName = ConfigurationManager.AppSettings["queueName"];  

    // Create the transacted MSMQ queue if necessary.  
    if (!MessageQueue.Exists(queueName))  
        MessageQueue.Create(queueName, true);  

    // Create a ServiceHost for the OrderProcessorService type.  
    using (ServiceHost serviceHost = new ServiceHost(typeof(OrderProcessorService)))  
    {  
        // Open the ServiceHost to create listeners and start listening for messages.  
        serviceHost.Open();  

        // The service can now be accessed.  
        Console.WriteLine("The service is ready.");  
        Console.WriteLine("Press <ENTER> to terminate service.");  
        Console.WriteLine();  
        Console.ReadLine();  
    }  
}  

Der Client erstellt eine Transaktion.The client creates a transaction. Die Kommunikation mit der Warteschlange findet innerhalb des Geltungsbereichs der Transaktion statt, sodass diese in der Folge als unteilbare Einheit behandelt wird, in der alle Nachrichten entweder erfolgreich sind oder fehlschlagen.Communication with the queue takes place within the scope of the transaction, causing it to be treated as an atomic unit where all messages succeed or fail.

// Create a ServiceHost for the OrderStatus service type.  
using (ServiceHost serviceHost = new ServiceHost(typeof(OrderStatusService)))  
{  

    // Open the ServiceHostBase to create listeners and start listening for order status messages.  
    serviceHost.Open();  

    // Create the purchase order.  
    ...  

    // Create a client with given client endpoint configuration.  
    OrderProcessorClient client = new OrderProcessorClient("OrderProcessorEndpoint");  

    //Create a transaction scope.  
    using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))  
    {  
        string hostName = Dns.GetHostName();  

        // Make a queued call to submit the purchase order.  
        client.SubmitPurchaseOrder(po, "net.msmq://" + hostName + "/private/ServiceModelSamplesTwo-way/OrderStatus");  

        // Complete the transaction.  
        scope.Complete();  
    }  

    //Close down the client.  
    client.Close();  

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

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

Der Clientcode implementiert den IOrderStatus-Vertrag, um den Auftragsstatus vom Dienst zu empfangen.The client code implements the IOrderStatus contract to receive order status from the service. In diesem Fall druckt er den Auftragsstatus aus.In this case, it prints out the order status.

[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.The order status queue is created in the Main method. Die Clientkonfiguration beinhaltet die Dienstkonfiguration für den Auftragsstatus, um den Auftragsstatusdienst zu hosten, wie in der folgenden Beispielkonfiguration dargestellt.The client configuration includes the order status service configuration to host the order status service, as shown in the following sample configuration.

<appSettings>  
  <!-- Use appSetting to configure MSMQ queue name. -->  
  <add key="queueName" value=".\private$\ServiceModelSamplesTwo-way/OrderStatus" />  
</appSettings>  

<system.serviceModel>  

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

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

</system.serviceModel>  

Wenn Sie das Beispiel ausführen, werden die Client- und Dienstaktivitäten sowohl im Dienst- als auch im Clientkonsolenfenster angezeigt.When you run the sample, the client and service activities are displayed in both the service and client console windows. Sie können sehen, wie der Dienst Nachrichten vom Client empfängt.You can see the service receive messages from the client. Drücken Sie die EINGABETASTE in den einzelnen Konsolenfenstern, um den Dienst und den Client zu schließen.Press ENTER in each console window to shut down the service and client.

Der Dienst zeigt die Bestellungsinformationen an und sendet sie für die Rücksendung an den Auftragsstatus an die Auftragsstatuswarteschlage.The service displays the purchase order information and indicates it is sending back the order status to the order status queue.

The service is ready.  
Press <ENTER> to terminate service.  

Processing Purchase Order: 124a1f69-3699-4b16-9bcc-43147a8756fc  
        Customer: somecustomer.com  
        OrderDetails  
                Order LineItem: 54 of Blue Widget @unit price: $29.99  
                Order LineItem: 890 of Red Widget @unit price: $45.89  
        Total cost of this order: $42461.56  
        Order status: Pending  

Sending back order status information  

Der Client zeigt die vom Dienst gesendeten Auftragsstatusinformationen an.The client displays the order status information sent by the service.

Press <ENTER> to terminate client.  
Status of order 124a1f69-3699-4b16-9bcc-43147a8756fc:Pending  

So können Sie das Beispiel einrichten, erstellen und ausführenTo set up, build, and run the sample

  1. Stellen Sie sicher, dass Sie ausgeführt haben die Setupprozedur für die Windows Communication Foundation-Beispiele zum einmaligen.Ensure that you have performed the One-Time Setup Procedure for the Windows Communication Foundation Samples.

  2. Um die C#- oder Visual Basic .NET-Edition der Projektmappe zu erstellen, befolgen Sie die unter Building the Windows Communication Foundation Samplesaufgeführten Anweisungen.To build the C# or Visual Basic .NET edition of the solution, follow the instructions in Building the Windows Communication Foundation Samples.

  3. Um das Beispiel in einer einzelnen oder computerübergreifenden Konfiguration ausführen möchten, folgen Sie den Anweisungen Ausführen der Windows Communication Foundation-Beispiele.To run the sample in a single- or cross-machine configuration, follow the instructions in Running the Windows Communication Foundation Samples.

    Hinweis

    Wenn Sie zur Neugenerierung der Konfiguration für dieses Beispiel die Datei "Svcutil.exe" verwenden, müssen Sie die Endpunktnamen in der Clientkonfiguration ändern, sodass sie mit dem Clientcode übereinstimmen.If you use Svcutil.exe to regenerate the configuration for this sample, be sure to modify the endpoint names in the client configuration to match the client code.

Standardmäßig wird mit NetMsmqBinding die Transportsicherheit aktiviert.By default with the NetMsmqBinding, transport security is enabled. Es gibt zwei relevante Eigenschaften für MSMQ-transportsicherheit MsmqAuthenticationMode und MsmqProtectionLevel . standardmäßig der Authentifizierungsmodus festgelegt ist, um Windows und die Schutzebene festgelegt ist, um Sign.There are two relevant properties for MSMQ transport security, MsmqAuthenticationMode and MsmqProtectionLevel. By default, the authentication mode is set to Windows and the protection level is set to Sign. Damit MSMQ die Authentifizierungs- und Signierungsfunktion bereitstellt, muss es Teil einer Domäne sein, und die Active Directory-Integrationsoption für MSMQ muss installiert sein.For MSMQ to provide the authentication and signing feature, it must be part of a domain and the active directory integration option for MSMQ must be installed. Wenn Sie dieses Beispiel auf einem Computer ausführen, der diese Kriterien nicht erfüllt, tritt ein Fehler auf.If you run this sample on a computer that does not satisfy these criteria you receive an error.

So führen Sie das Beispiel auf einem Computer aus, der sich in einer Arbeitsgruppe befindet oder über keine Active Directory-Integration verfügtTo run the sample on a computer joined to a workgroup or without active directory integration

  1. Wenn Ihr Computer nicht zu einer Domäne gehört oder auf ihm keine Active Directory-Integration installiert ist, deaktivieren Sie die Transportsicherheit, indem Sie den Authentifizierungsmodus und die Schutzebene auf None setzen, wie in der folgenden Beispielkonfiguration gezeigt.If your computer is not part of a domain or does not have active directory integration installed, turn off transport security by setting the authentication mode and protection level to None as shown in the following sample configuration:

    <configuration>  
    
      <appSettings>  
        <!-- Use appSetting to configure MSMQ queue name. -->  
        <add key="queueName" value=".\private$\ServiceModelSamplesTwo-way/OrderProcessor" />  
      </appSettings>  
    
      <system.serviceModel>  
        <services>  
          <service   
              name="Microsoft.ServiceModel.Samples.OrderProcessorService">  
            <!-- Define NetMsmqEndpoint -->  
            <endpoint address="net.msmq://localhost/private/ServiceModelSamplesTwo-way/OrderProcessor"  
                      binding="netMsmqBinding"  
                      bindingConfiguration="TransactedBinding"   
                      contract="Microsoft.ServiceModel.Samples.IOrderProcessor" />  
          </service>  
        </services>  
    
        <bindings>  
          <netMsmqBinding>  
            <binding name="TransactedBinding" >  
             <security mode="None" />  
            </binding>  
          </netMsmqBinding>  
        </bindings>  
    
      </system.serviceModel>  
    
    </configuration>  
    
  2. Wenn die Sicherheit für eine Clientkonfiguration deaktiviert wird, wird Folgendes generiert:Turning off security for a client configuration generates the following:

    <?xml version="1.0" encoding="utf-8" ?>  
    <configuration>  
      <appSettings>  
        <!-- Use appSetting to configure MSMQ queue name. -->  
        <add key="queueName" value=".\private$\ServiceModelSamplesTwo-way/OrderStatus" />  
      </appSettings>  
    
      <system.serviceModel>  
    
        <services>  
          <service   
             name="Microsoft.ServiceModel.Samples.OrderStatusService">  
            <!-- Define NetMsmqEndpoint -->  
            <endpoint address="net.msmq://localhost/private/ServiceModelSamplesTwo-way/OrderStatus"  
                      binding="netMsmqBinding"  
                      bindingConfiguration="TransactedBinding" contract="Microsoft.ServiceModel.Samples.IOrderStatus" />  
          </service>  
        </services>  
    
        <client>  
          <!-- Define NetMsmqEndpoint -->  
          <endpoint name="OrderProcessorEndpoint"  
                    address="net.msmq://localhost/private/ServiceModelSamplesTwo-way/OrderProcessor"   
                    binding="netMsmqBinding"   
                    bindingConfiguration="TransactedBinding"  
                    contract="Microsoft.ServiceModel.Samples.IOrderProcessor" />  
        </client>  
    
        <bindings>  
          <netMsmqBinding>  
            <binding name="TransactedBinding" >  
             <security mode="None" />  
            </binding>  
          </netMsmqBinding>  
        </bindings>  
    
      </system.serviceModel>  
    
    </configuration>  
    
  3. Der Dienst für dieses Beispiel erstellt eine Bindung im OrderProcessorService.The service for this sample creates a binding in the OrderProcessorService. Fügen Sie eine Codezeile hinzu, nachdem die Bindung instanziiert wurde, um den Sicherheitsmodus auf None festzulegen.Add a line of code after the binding is instantiated to set the security mode to None.

    NetMsmqBinding msmqCallbackBinding = new NetMsmqBinding();  
    msmqCallbackBinding.Security.Mode = NetMsmqSecurityMode.None;  
    
  4. Ändern Sie die Konfiguration sowohl auf dem Server als auch auf dem Client, bevor Sie das Beispiel ausführen.Ensure that you change the configuration on both the server and the client before you run the sample.

    Hinweis

    Das Festlegen von security mode auf None entspricht dem Festlegen von MsmqAuthenticationMode, MsmqProtectionLevel oder der Message-Sicherheit auf None.Setting security mode to None is equivalent to setting MsmqAuthenticationMode, MsmqProtectionLevel or Message security to None.

Wichtig

Die Beispiele sind möglicherweise bereits auf dem Computer installiert.The samples may already be installed on your machine. Suchen Sie nach dem folgenden Verzeichnis (Standardverzeichnis), bevor Sie fortfahren.Check for the following (default) directory before continuing.

<InstallDrive>:\WF_WCF_Samples

Wenn dieses Verzeichnis nicht vorhanden ist, rufen Sie Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF) Samples for .NET Framework 4 auf, um alle Windows Communication Foundation (WCF)Windows Communication Foundation (WCF) - und WFWF -Beispiele herunterzuladen.If this directory does not exist, go to Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF) Samples for .NET Framework 4 to download all Windows Communication Foundation (WCF)Windows Communication Foundation (WCF) and WFWF samples. Dieses Beispiel befindet sich im folgenden Verzeichnis.This sample is located in the following directory.

<InstallDrive>:\WF_WCF_Samples\WF\Basic\Binding\Net\MSMQ\Two-Way

Siehe auchSee Also