Partilhar via


Como fazer: Trocar mensagens com pontos de extremidade WCF e aplicações de filas de mensagens

Você pode integrar aplicações existentes de Fila de Mensagens (MSMQ) com aplicações Windows Communication Foundation (WCF) usando a ligação de integração MSMQ para converter mensagens MSMQ para e a partir de mensagens WCF. Isso permite que você ligue para aplicativos recetores MSMQ a partir de clientes WCF, bem como ligue para serviços WCF a partir de aplicativos remetentes MSMQ.

Nesta seção, explicamos como usar o MsmqIntegrationBinding para comunicação em fila entre (1) um cliente WCF e um serviço de aplicativo MSMQ escrito usando System.Messaging e (2) um cliente de aplicativo MSMQ e um serviço WCF.

Para obter um exemplo completo que demonstra como chamar uma aplicação recetora de MSMQ a partir de um cliente WCF, consulte o exemplo do Windows Communication Foundation para Message Queuing.

Para obter um exemplo completo que demonstra como chamar um serviço WCF de um cliente MSMQ, consulte o Message Queuing to Windows Communication Foundation exemplo.

Para criar um serviço WCF que recebe mensagens de um cliente MSMQ

  1. Defina uma interface que defina o contrato de serviço para o serviço WCF que recebe mensagens enfileiradas de um aplicativo remetente MSMQ, conforme mostrado no código de exemplo a seguir.

    [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. Implemente a interface e aplique o atributo ServiceBehaviorAttribute à classe, conforme mostrado no código de exemplo a seguir.

    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. Crie um arquivo de configuração que especifique o MsmqIntegrationBinding.

  4. Instancie um objeto ServiceHost que usa a associação configurada.

Para criar um cliente WCF que envia mensagens para um aplicativo recetor MSMQ

  1. Defina uma interface que defina o contrato de serviço para o cliente WCF que envia mensagens enfileiradas para o recetor MSMQ, conforme mostrado no código de exemplo a seguir.

    [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. Defina uma classe de cliente que o cliente WCF usa para chamar o recetor 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. Crie uma configuração que especifique o uso da associação MsmqIntegrationBinding.

    MsmqIntegrationBinding binding = new MsmqIntegrationBinding("MyBindingConfig");
    
    Dim binding As New MsmqIntegrationBinding("MyBindingConfig")
    
  4. Crie uma instância da classe client e chame o método definido pelo serviço de recebimento de mensagens.

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

Ver também