Cómo: Intercambiar mensajes con extremos de WCF y aplicaciones de Message Queue Server
Puede integrar aplicaciones Message Queue Server existentes (MSMQ) con aplicaciones de Windows Communication Foundation (WCF) utilizando el enlace de integración de MSMQ para convertir los mensajes de MSMQ a y desde mensajes de WCF. Esto le permite llamar a aplicaciones de receptor de MSMQ desde clientes de WCF, así como llamar a servicios de WCF desde aplicaciones de remitente de MSMQ.
En esta sección, explicamos cómo utilizar MsmqIntegrationBinding para la comunicación en cola entre (1) un cliente de WCF y un servicio de aplicación de MSMQ escrito al usar System.Messaging y (2) un cliente de aplicación de MSMQ y un servicio de WCF.
Para obtener un ejemplo completo donde se muestra cómo llamar a una aplicación receptora de MSMQ desde un cliente WCF, vea el ejemplo Windows Communication Foundation a Message Queuing.
Para obtener un ejemplo completo donde se muestra cómo llamar a un servicio WCF desde un cliente MSMQ, vea el ejemplo Message Queuing a Windows Communication Foundation.
Para crear un servicio WCF que reciba mensajes desde un cliente de MSMQ
Defina una interfaz que defina el contrato de servicio para el servicio de WCF que recibe los mensajes en cola desde una aplicación remitente de MSMQ, como se muestra en el siguiente ejemplo de código.
<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); }
Implemente la interfaz y aplique el atributo ServiceBehaviorAttribute a la clase, como se muestra en el código de ejemplo siguiente.
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(); } } }
Cree un archivo de configuración que especifique MsmqIntegrationBinding.
<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>
Cree una instancia de un objeto ServiceHost que utilice el enlace configurado.
Para crear un cliente de WCF que envíe mensajes a una aplicación de receptor de MSMQ
Defina una interfaz que defina el contrato de servicio para el cliente de WCF que envía mensajes en cola al receptor de MSMQ, como se muestra en el código de ejemplo siguiente.
<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 { }
Defina una clase de cliente que el cliente de WCF usará para llamar al receptor de MSMQ.
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);
Cree una configuración que especifique el uso del enlace MsmqIntegrationBinding.
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>
Cree una instancia de la clase de cliente y llame al método definido por el servicio de recepción de mensajes.
// 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();
Vea también
Tareas
Cómo: Intercambiar mensajes en cola con extremos de WCF
Windows Communication Foundation a Message Queuing
Message Queuing a Windows Communication Foundation
Seguridad del mensaje mediante Message Queuing
Conceptos
Información general de colas
Instalar Message Queuing (MSMQ)