Vorgehensweise: Nachrichtenaustausch mit WCF-Endpunkten und Message Queuing-Anwendungen

Sie können vorhandene Message Queuing (MSMQ)- Anwendungen mit Windows Communication Foundation (WCF)-Anwendungen integrieren, indem Sie mithilfe der Bindung für die MSMQ-Integration MSMQ-Nachrichten in WCF-Nachrichten und WCF-Nachrichten in MSMQ-Nachrichten konvertieren. So können Sie mit WCF-Clients MSMQ-Empfängeranwendungen und mit MSMQ-Sendeanwendungen WCF-Dienste aufrufen.

In diesem Abschnitt wird erläutert, wie Sie MsmqIntegrationBinding für die Warteschlangenkommunikation zwischen (1) einem WCF-Client und einem mit System.Messaging geschriebenen MSMQ-Anwendungsdienst und (2) einem MSMQ-Anwendungsclient und einem WCF-Dienst verwenden können.

Ein vollständiges Beispiel, in dem das Aufrufen einer MSMQ-Empfängeranwendung von einem WCF-Client aus veranschaulicht wird, finden Sie im Beispiel unter Windows Communication Foundation zu Message Queuing.

Ein vollständiges Beispiel, in dem das Aufrufen eines WCF-Diensts von einem MSMQ-Client aus veranschaulicht wird, finden Sie im Beispiel unter Message Queuing zu Windows Communication Foundation.

So erstellen Sie einen WCF-Dienst, der Nachrichten von einem MSMQ-Client empfängt

  1. Definieren Sie wie im folgenden Beispielcode gezeigt eine Schnittstelle, die den Dienstvertrag für den WCF-Dienst definiert, der die über eine Warteschlange geleiteten Nachrichten einer MSMQ-Sendeanwendung empfängt:

    <ServiceContract(Namespace:="http:'Microsoft.ServiceModel.Samples")> _
    <ServiceKnownType(GetType(PurchaseOrder))> _
    Public Interface IOrderProcessor
        <OperationContract(IsOneWay:=True, Action:="*")> _
        Sub SubmitPurchaseOrder(ByVal msg As MsmqMessage(Of PurchaseOrder))
    End Interface
    
    [ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
    [ServiceKnownType(typeof(PurchaseOrder))]
    public interface IOrderProcessor
    {
        [OperationContract(IsOneWay = true, Action = "*")]
        void SubmitPurchaseOrder(MsmqMessage<PurchaseOrder> msg);
    }
    
  2. Implementieren Sie die Schnittstelle, und wenden Sie das ServiceBehaviorAttribute-Attribut wie im folgenden Beispielcode gezeigt auf die Klasse an.

    Public Class OrderProcessorService
        Implements IOrderProcessor
    
        <OperationBehavior(TransactionScopeRequired:=True, TransactionAutoComplete:=True)> _
        Public Sub SubmitPurchaseOrder(ByVal ordermsg As MsmqMessage(Of PurchaseOrder)) Implements IOrderProcessor.SubmitPurchaseOrder
            Dim po As PurchaseOrder = ordermsg.Body
            Dim statusIndexer As New Random()
            po.Status = statusIndexer.Next(3)
            Console.WriteLine("Processing {0} ", po)
        End Sub
    End Class
    
    public class OrderProcessorService : IOrderProcessor
    {
        [OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
        public void SubmitPurchaseOrder(MsmqMessage<PurchaseOrder> ordermsg)
        {
            PurchaseOrder po = (PurchaseOrder)ordermsg.Body;
            Random statusIndexer = new Random();
            po.Status = (OrderStates)statusIndexer.Next(3);
            Console.WriteLine("Processing {0} ", po);
        }
    
        // Host the service within this EXE console application.
    public static void Main()
    {
        // Get base address from appsettings in configuration.
        Uri baseAddress = new Uri(ConfigurationManager.AppSettings["baseAddress"]);
    
        // Create a ServiceHost for the CalculatorService type and provide the base address.
        using (ServiceHost serviceHost = new ServiceHost(typeof(IOrderProcessor), baseAddress))
        {
        // Open the ServiceHostBase to create listeners and start listening for messages.
            serviceHost.Open();
    
        // The service can now be accessed.
            Console.WriteLine("The service is ready.");
            Console.WriteLine("The service is running in the following account: {0}", WindowsIdentity.GetCurrent().Name);
            Console.WriteLine("Press <ENTER> to terminate service.");
            Console.WriteLine();
            Console.ReadLine();
    
        // Close the ServiceHostBase to shutdown the service.
            serviceHost.Close();
        }
    }
    
    }
    
  3. Erstellen Sie eine Konfigurationsdatei, die die MsmqIntegrationBinding angibt.

    <configuration>
      <appSettings>
        <!-- use appSetting to configure MSMQ queue name -->
        <add key="orderQueueName" value=".\private$\Orders" />
        <add key="baseAddress" value="https://localhost:8000/ServiceModelSamples/Service" />
      </appSettings>
      <system.serviceModel>
        <services>
          <service 
            name="Microsoft.ServiceModel.Samples.OrderProcessorService" >
            <endpoint address="msmq.formatname:DIRECT=OS:.\private$\Orders"
                                    binding="msmqIntegrationBinding"
                      bindingConfiguration="OrderProcessorBinding" 
                      contract="Microsoft.ServiceModel.Samples.IOrderProcessor">
            </endpoint>
          </service>
        </services>
    
        <bindings>
          <msmqIntegrationBinding>
            <binding name="OrderProcessorBinding" >
              <security mode="None" />
            </binding>
          </msmqIntegrationBinding>
        </bindings>
    
      </system.serviceModel >
    
    </configuration>
    
  4. Instanziieren Sie ein ServiceHost-Objekt, das die konfigurierte Bindung verwendet.

So erstellen Sie einen WCF-Client, der Nachrichten an eine MSMQ-Empfängeranwendung sendet

  1. Definieren Sie wie im folgenden Beispielcode gezeigt eine Schnittstelle, die den Dienstvertrag für den WCF-Client definiert, der über eine Warteschlange geleitete Nachrichten an den MSMQ-Empfänger sendet:

    <System.ServiceModel.ServiceContractAttribute(Namespace:="http:'Microsoft.ServiceModel.Samples")> _
    Public Interface IOrderProcessor
        <OperationContract(IsOneWay:=True, Action:="*")> _
        Sub SubmitPurchaseOrder(ByVal msg As MsmqMessage(Of PurchaseOrder))
    end interface
    
    Public Interface IOrderProcessorChannel
        Inherits IOrderProcessor, System.ServiceModel.IClientChannel
    End Interface
    
    [System.ServiceModel.ServiceContractAttribute(Namespace = "http://Microsoft.ServiceModel.Samples")]
    public interface IOrderProcessor
    {
        [OperationContract(IsOneWay = true, Action = "*")]
        void SubmitPurchaseOrder(MsmqMessage<PurchaseOrder> msg);
    }
    
    public interface IOrderProcessorChannel : IOrderProcessor, System.ServiceModel.IClientChannel
    {
    }
    
  2. Definieren Sie eine Clientklasse, über die der WCF-Client den MSMQ-Empfänger aufruft.

    Dim binding As New MsmqIntegrationBinding()
    Dim address As New EndpointAddress("msmq.formatname:DIRECT=OS:.\\private$\\Orders")
    Dim channelFactory As New ChannelFactory(Of IOrderProcessor)(binding, address)
    Dim channel As IOrderProcessor = channelFactory.CreateChannel()
    
    Dim po As New PurchaseOrder()
    po.customerId = "somecustomer.com"
    po.poNumber = Guid.NewGuid().ToString()
    
    Dim lineItem1 As New PurchaseOrderLineItem()
    lineItem1.productId = "Blue Widget"
    lineItem1.quantity = 54
    lineItem1.unitCost = 29.99F
    
    Dim lineItem2 = New PurchaseOrderLineItem()
    lineItem2.productId = "Red Widget"
    lineItem2.quantity = 890
    lineItem2.unitCost = 45.89F
    
    Dim lineItems(2) As PurchaseOrderLineItem
    lineItems(0) = lineItem1
    lineItems(1) = lineItem2
    
    po.orderLineItems = lineItems
    
    Dim ordermsg As MsmqMessage(Of PurchaseOrder) = New MsmqMessage(Of PurchaseOrder)(po)
    Using scope As New TransactionScope(TransactionScopeOption.Required)
        channel.SubmitPurchaseOrder(ordermsg)
        scope.Complete()
    End Using
    Console.WriteLine("Order has been submitted:{0}", po)
    
    MsmqIntegrationBinding binding = new MsmqIntegrationBinding();
    EndpointAddress address = new EndpointAddress("msmq.formatname:DIRECT=OS:.\\private$\\Orders");
    ChannelFactory<IOrderProcessor> channelFactory = new ChannelFactory<IOrderProcessor>(binding, address);
    IOrderProcessor channel = channelFactory.CreateChannel();
    
    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;
    
    
    MsmqMessage<PurchaseOrder> ordermsg = new MsmqMessage<PurchaseOrder>(po);
    using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
    {
        channel.SubmitPurchaseOrder(ordermsg);
        scope.Complete();
    }
    Console.WriteLine("Order has been submitted:{0}", po);
    
  3. Erstellen Sie eine Konfiguration, die die Verwendung der MsmqIntegrationBinding-Bindung angibt.

    Dim binding As New MsmqIntegrationBinding("MyBindingConfig")
    
    MsmqIntegrationBinding binding = new MsmqIntegrationBinding("MyBindingConfig");
    
    <configuration>
        <system.serviceModel>
    
        <client>
          <endpoint  name="OrderResponseEndpoint" 
                    address="msmq.formatname:DIRECT=OS:.\private$\Orders"
                    binding="msmqIntegrationBinding"
                    bindingConfiguration="OrderProcessorBinding" 
                    contract="Microsoft.ServiceModel.Samples.IOrderProcessor">
          </endpoint>
        </client>
    
        <bindings>
          <msmqIntegrationBinding>
            <binding name="OrderProcessorBinding" >
              <security mode="None" />
            </binding>
          </msmqIntegrationBinding>
        </bindings>
    
      </system.serviceModel>
    
    </configuration>
    
  4. Erstellen Sie eine Instanz der Clientklasse, und rufen Sie die vom Nachrichten empfangenden Dienst definierte Methode auf.

    // 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;
    
    OrderProcessorClient client = new OrderProcessorClient("OrderResponseEndpoint");
    MsmqMessage<PurchaseOrder> ordermsg = new MsmqMessage<PurchaseOrder>(po);
    using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
    {
        client.SubmitPurchaseOrder(ordermsg);
        scope.Complete();
    }
    
    Console.WriteLine("Order has been submitted:{0}", po);
    
    //Closing the client gracefully closes the connection and cleans up resources.
    client.Close();
    
    Console.WriteLine();
    Console.WriteLine("Press <ENTER> to terminate client.");
    Console.ReadLine();
    

Siehe auch

Aufgaben

Gewusst wie: Austauschen von Nachrichten in einer Warteschlange mit WCD-Endpunkten
Windows Communication Foundation zu Message Queuing
Message Queuing zu Windows Communication Foundation
Nachrichtensicherheit über Message Queuing

Konzepte

Warteschlangenübersicht
Installieren von Message Queuing (MSMQ)

Weitere Ressourcen

Message Queuing Integration Binding Samples