共用方式為


如何:與 WCF 端點和消息佇列應用程式交換訊息

您可以使用 MSMQ 整合系結,將現有的消息佇列 (MSMQ) 應用程式與 Windows Communication Foundation (WCF) 應用程式整合,以將 MSMQ 訊息轉換成 WCF 訊息。 這可讓您從 WCF 用戶端呼叫 MSMQ 接收者應用程式,以及從 MSMQ 傳送者應用程式呼叫 WCF 服務。

在本節中,我們將說明如何使用 MsmqIntegrationBinding 在 (1) WCF 用戶端與使用 System.Messaging 撰寫的 MSMQ 應用程式服務,以及 (2) MSMQ 應用程式用戶端與 WCF 服務之間進行佇列通訊。

如需示範如何從 WCF 用戶端呼叫 MSMQ 接收者應用程式的完整範例,請參閱 Windows Communication Foundation to Message Queuing 範例。

如需示範如何從 MSMQ 用戶端呼叫 WCF 服務的完整範例,請參閱 消息佇列至 Windows Communication Foundation 範例。

建立從 MSMQ 用戶端接收訊息的 WCF 服務

  1. 定義介面,定義 WCF 服務的服務合約,此服務會從 MSMQ 傳送者應用程式接收佇列訊息,如下列範例程式代碼所示。

    [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. 實作 介面並將 屬性套用 ServiceBehaviorAttribute 至 類別,如下列範例程式代碼所示。

    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 {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: {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. 建立指定的 MsmqIntegrationBinding組態檔。

  4. 請實例化一個使用已設定繫結的ServiceHost物件。

建立 WCF 用戶端,以將訊息傳送至 MSMQ 接收者應用程式

  1. 定義介面,定義 WCF 用戶端的服務合約,以將佇列訊息傳送至 MSMQ 接收者,如下列範例程式代碼所示。

    [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. 定義 WCF 用戶端用來呼叫 MSMQ 接收者的客戶端類別。

    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:{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(1) 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. 建立組態,指定使用 MsmqIntegrationBinding 系結。

    MsmqIntegrationBinding binding = new MsmqIntegrationBinding("MyBindingConfig");
    
    Dim binding As New MsmqIntegrationBinding("MyBindingConfig")
    
  4. 建立客戶端類別的實例,並呼叫訊息接收服務所定義的方法。

    // 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:{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();
    

另請參閱