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 mit MsmqIntegrationBinding für die warteschlangenkommunikation zwischen (1) ein WCF Client und ein MSMQ-Anwendungsdienst mit System.Messaging und (2) einem MSMQ-Anwendungsclient geschrieben und ein WCF Service.

Ein vollständiges Beispiel, das veranschaulicht, wie eine MSMQ-empfängeranwendung von einer WCF -Client finden Sie unter der Windows Communication Foundation zu Message Queuing- Beispiel.

Ein vollständiges Beispiel, das veranschaulicht, wie eine WCF service aus einem MSMQ-Client, finden Sie unter der Message Queuing zu Windows Communication Foundation Beispiel.

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(typeof(PurchaseOrder))]
    public interface IOrderProcessor
    {
        [OperationContract(IsOneWay = true, Action = "*")]
        void SubmitPurchaseOrder(MsmqMessage<PurchaseOrder> msg);
    }
    
    <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
    
  2. Die-Schnittstelle implementieren und Anwenden der ServiceBehaviorAttribute -Attribut auf die Klasse, wie im folgenden Beispielcode gezeigt.

       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();
    	}
    }
    
       }
    
    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
    
  3. Eine Konfigurationsdatei erstellen, die angibt, die MsmqIntegrationBinding.

  4. Instanziieren einer 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 = "*")]
        void SubmitPurchaseOrder(MsmqMessage<PurchaseOrder> msg);
    }
    
    public interface IOrderProcessorChannel : IOrderProcessor, System.ServiceModel.IClientChannel
    {
    }
    
    <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
    
  2. Definieren Sie eine Clientklasse, über die der WCF-Client den MSMQ-Empfänger aufruft.

    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);
    
    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)
    
  3. Erstellen Sie eine Konfiguration, die die Verwendung der MsmqIntegrationBinding-Bindung angibt.

    MsmqIntegrationBinding binding = new MsmqIntegrationBinding("MyBindingConfig");
    
    Dim binding As New MsmqIntegrationBinding("MyBindingConfig")
    
  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

Nachrichtenwarteschlangen (Übersicht)
Gewusst wie: Austauschen in einer Warteschlange Nachrichten mit WCF-Endpunkten
Windows Communication Foundation zu Message Queuing
Installieren von Message Queuing (MSMQ)
Message Queuing zu Windows Communication Foundation
Nachrichtensicherheit über Message Queuing