Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En el ejemplo de Bidireccional, se muestra cómo llevar a cabo la comunicación en cola bidireccional sobre MSMQ. El ejemplo usa el enlace netMsmqBinding. En este caso, el servicio es una aplicación de consola autogestionada que permite observar cómo el servicio recibe mensajes en cola.
Nota:
El procedimiento de instalación y las instrucciones de compilación de este ejemplo se encuentran al final de este tema.
Este ejemplo se basa en el enlace MSMQ por transacciones.
En la comunicación con colas, el cliente se comunica con el servicio mediante una cola. El cliente envía mensajes a una cola y el servicio recibe mensajes de la cola. El servicio y el cliente no necesitan ejecutarse simultáneamente para comunicarse mediante una cola.
En este ejemplo se muestra la comunicación bidireccional mediante colas. El cliente envía los pedidos de compra a la cola desde dentro del ámbito de una transacción. El servicio recibe las órdenes, procesa la orden y, a continuación, llama de nuevo al cliente con el estado de la orden desde la cola dentro del ámbito de una transacción. Para facilitar la comunicación bidireccional, tanto el cliente como el servicio utilizan las colas para poner en cola los pedidos de compra y el estado de la orden.
El contrato IOrderProcessor de servicio define operaciones de servicio unidireccionales que se adaptan al uso de colas. La operación del servicio incluye el punto de conexión de la respuesta para utilizarlo para enviar los estados del orden. El punto de conexión de la respuesta es el URI de la cola para devolver el estado de la orden al cliente. La aplicación de procesamiento de pedidos implementa este contrato.
[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples")]
public interface IOrderProcessor
{
[OperationContract(IsOneWay = true)]
void SubmitPurchaseOrder(PurchaseOrder po, string
reportOrderStatusTo);
}
El cliente especifica el contrato de la respuesta para enviar el estado de la orden. El cliente implementa el contrato sobre el estado del pedido. El servicio usa el proxy generado de este contrato para devolver el estado del pedido al cliente.
[ServiceContract]
public interface IOrderStatus
{
[OperationContract(IsOneWay = true)]
void OrderStatus(string poNumber, string status);
}
La operación de servicio procesa el pedido de compra enviado.
OperationBehaviorAttribute se aplica a la operación del servicio para especificar la inscripción automática en una transacción que se utiliza para recibir el mensaje de la cola y la realización automática de transacciones en la realización de la operación del servicio. La Orders clase encapsula la funcionalidad de procesamiento de pedidos. En este caso, agrega el pedido de compra a un diccionario. La transacción en la que está inscrita la operación de servicio está disponible para las operaciones de la clase Orders.
La operación de servicio, además de procesar el pedido de compra enviado, informa al cliente sobre el estado del pedido.
[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
public void SubmitPurchaseOrder(PurchaseOrder po, string reportOrderStatusTo)
{
Orders.Add(po);
Console.WriteLine("Processing {0} ", po);
Console.WriteLine("Sending back order status information");
NetMsmqBinding msmqCallbackBinding = new NetMsmqBinding("ClientCallbackBinding");
OrderStatusClient client = new OrderStatusClient(msmqCallbackBinding, new EndpointAddress(reportOrderStatusTo));
// Please note that the same transaction that is used to dequeue the purchase order is used
// to send back order status.
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
{
client.OrderStatus(po.PONumber, po.Status);
scope.Complete();
}
//Close the client.
client.Close();
}
El nombre de cola de MSMQ se especifica en una sección appSettings del archivo de configuración. El punto de conexión del servicio se define en la sección System.ServiceModel del archivo de configuración.
Nota:
El nombre de cola de MSMQ y la dirección de extremo utilizan convenciones de direccionamiento ligeramente diferentes. El nombre de la cola MSMQ utiliza un punto (.) para el equipo local y separadores con barra diagonal inversa en su ruta de acceso. La dirección de punto de conexión de Windows Communication Foundation (WCF) especifica un esquema net.msmq:, utiliza "localhost" para el equipo local y utiliza barras diagonales en su ruta de acceso. Para leer de una cola que se hospeda en el equipo remoto, reemplace el "." y el “host local” por el nombre del equipo remoto.
El servicio se hospeda en sí mismo. Al utilizar el transporte de MSMQ, se debe crear la cola utilizada de antemano. Esto se puede hacer manualmente o a través del código. En este ejemplo, el servicio comprueba la existencia de la cola y lo crea, si es necesario. El nombre de la cola se lee del archivo de configuración. La herramienta de utilidad de metadatos ServiceModel (Svcutil.exe) usa la dirección base para generar el proxy para el servicio.
// Host the service within this EXE console application.
public static void Main()
{
// Get MSMQ queue name from appSettings in configuration.
string queueName = ConfigurationManager.AppSettings["queueName"];
// Create the transacted MSMQ queue if necessary.
if (!MessageQueue.Exists(queueName))
MessageQueue.Create(queueName, true);
// Create a ServiceHost for the OrderProcessorService type.
using (ServiceHost serviceHost = new ServiceHost(typeof(OrderProcessorService)))
{
// Open the ServiceHost to create listeners and start listening for messages.
serviceHost.Open();
// The service can now be accessed.
Console.WriteLine("The service is ready.");
Console.WriteLine("Press <ENTER> to terminate service.");
Console.WriteLine();
Console.ReadLine();
}
}
El cliente crea una transacción. La comunicación con la cola tiene lugar dentro del ámbito de la transacción, lo que hace que se trate como una unidad atómica donde todos los mensajes tienen éxito o fracasan.
// Create a ServiceHost for the OrderStatus service type.
using (ServiceHost serviceHost = new ServiceHost(typeof(OrderStatusService)))
{
// Open the ServiceHostBase to create listeners and start listening for order status messages.
serviceHost.Open();
// Create the purchase order.
...
// Create a client with given client endpoint configuration.
OrderProcessorClient client = new OrderProcessorClient("OrderProcessorEndpoint");
//Create a transaction scope.
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required))
{
string hostName = Dns.GetHostName();
// Make a queued call to submit the purchase order.
client.SubmitPurchaseOrder(po, "net.msmq://" + hostName + "/private/ServiceModelSamplesTwo-way/OrderStatus");
// Complete the transaction.
scope.Complete();
}
//Close down the client.
client.Close();
Console.WriteLine();
Console.WriteLine("Press <ENTER> to terminate client.");
Console.ReadLine();
// Close the ServiceHost to shutdown the service.
serviceHost.Close();
}
El código de cliente implementa el IOrderStatus contrato para recibir el estado del pedido del servicio. En este caso, imprime el estado del pedido.
[ServiceBehavior]
public class OrderStatusService : IOrderStatus
{
[OperationBehavior(TransactionAutoComplete = true,
TransactionScopeRequired = true)]
public void OrderStatus(string poNumber, string status)
{
Console.WriteLine("Status of order {0}:{1} ", poNumber ,
status);
}
}
La cola de estado del pedido se crea en el método Main. La configuración del cliente incluye la configuración del servicio de estado de pedido para hospedar el servicio de estado del pedido, como se muestra en la siguiente configuración de ejemplo.
<appSettings>
<!-- Use appSetting to configure MSMQ queue name. -->
<add key="queueName" value=".\private$\ServiceModelSamplesTwo-way/OrderStatus" />
</appSettings>
<system.serviceModel>
<services>
<service
name="Microsoft.ServiceModel.Samples.OrderStatusService">
<!-- Define NetMsmqEndpoint -->
<endpoint address="net.msmq://localhost/private/ServiceModelSamplesTwo-way/OrderStatus"
binding="netMsmqBinding"
contract="Microsoft.ServiceModel.Samples.IOrderStatus" />
</service>
</services>
<client>
<!-- Define NetMsmqEndpoint -->
<endpoint name="OrderProcessorEndpoint"
address="net.msmq://localhost/private/ServiceModelSamplesTwo-way/OrderProcessor"
binding="netMsmqBinding"
contract="Microsoft.ServiceModel.Samples.IOrderProcessor" />
</client>
</system.serviceModel>
Al ejecutar el ejemplo, las actividades de cliente y servicio se muestran en las ventanas de servicio y consola de cliente. Puede ver que el servicio recibe mensajes del cliente. Presione Entrar en cada ventana de la consola para cerrar el servicio y el cliente.
El servicio muestra la información del pedido de compra e indica que se está devolviendo el estado de la orden a la cola de estado de la orden.
The service is ready.
Press <ENTER> to terminate service.
Processing Purchase Order: 124a1f69-3699-4b16-9bcc-43147a8756fc
Customer: somecustomer.com
OrderDetails
Order LineItem: 54 of Blue Widget @unit price: $29.99
Order LineItem: 890 of Red Widget @unit price: $45.89
Total cost of this order: $42461.56
Order status: Pending
Sending back order status information
El cliente muestra la información de estado del pedido enviada por el servicio.
Press <ENTER> to terminate client.
Status of order 124a1f69-3699-4b16-9bcc-43147a8756fc:Pending
Para configurar, compilar y ejecutar el ejemplo
Asegúrese de que ha realizado el procedimiento de instalación única para los ejemplos de Windows Communication Foundation.
Para compilar el código C# o Visual Basic .NET Edition de la solución, siga las instrucciones de Building the Windows Communication Foundation Samples.
Para ejecutar el ejemplo en una configuración de una sola máquina o de varias máquinas, siga las instrucciones que se indican en Ejecución de los ejemplos de Windows Communication Foundation.
Nota:
Si usa Svcutil.exe para volver a generar la configuración de este ejemplo, asegúrese de modificar los nombres de punto de conexión de la configuración de cliente para que coincidan con el código de cliente.
De forma predeterminada, con NetMsmqBinding, la seguridad de transporte está habilitada. Hay dos propiedades relevantes para la seguridad de transporte de MSMQ, MsmqAuthenticationMode y MsmqProtectionLevel.. De forma predeterminada, el modo de autenticación se establece en Windows y el nivel de protección se establece en Sign. Para que MSMQ proporcione la característica de autenticación y firma, debe formar parte de un dominio y la opción de integración de Active Directory para MSMQ debe estar instalada. Si ejecuta este ejemplo en un equipo que no cumple estos criterios, recibirá un error.
Para ejecutar el ejemplo en un equipo unido a un grupo de trabajo o sin integración de Active Directory
Si el equipo no forma parte de un dominio o no tiene instalada la integración de Active Directory, desactive la seguridad de transporte estableciendo el modo de autenticación y el nivel
Nonede protección en como se muestra en la siguiente configuración de ejemplo:<configuration> <appSettings> <!-- Use appSetting to configure MSMQ queue name. --> <add key="queueName" value=".\private$\ServiceModelSamplesTwo-way/OrderProcessor" /> </appSettings> <system.serviceModel> <services> <service name="Microsoft.ServiceModel.Samples.OrderProcessorService"> <!-- Define NetMsmqEndpoint --> <endpoint address="net.msmq://localhost/private/ServiceModelSamplesTwo-way/OrderProcessor" binding="netMsmqBinding" bindingConfiguration="TransactedBinding" contract="Microsoft.ServiceModel.Samples.IOrderProcessor" /> </service> </services> <bindings> <netMsmqBinding> <binding name="TransactedBinding" > <security mode="None" /> </binding> </netMsmqBinding> </bindings> </system.serviceModel> </configuration>Desactivar la seguridad de una configuración de cliente genera lo siguiente:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <appSettings> <!-- Use appSetting to configure MSMQ queue name. --> <add key="queueName" value=".\private$\ServiceModelSamplesTwo-way/OrderStatus" /> </appSettings> <system.serviceModel> <services> <service name="Microsoft.ServiceModel.Samples.OrderStatusService"> <!-- Define NetMsmqEndpoint --> <endpoint address="net.msmq://localhost/private/ServiceModelSamplesTwo-way/OrderStatus" binding="netMsmqBinding" bindingConfiguration="TransactedBinding" contract="Microsoft.ServiceModel.Samples.IOrderStatus" /> </service> </services> <client> <!-- Define NetMsmqEndpoint --> <endpoint name="OrderProcessorEndpoint" address="net.msmq://localhost/private/ServiceModelSamplesTwo-way/OrderProcessor" binding="netMsmqBinding" bindingConfiguration="TransactedBinding" contract="Microsoft.ServiceModel.Samples.IOrderProcessor" /> </client> <bindings> <netMsmqBinding> <binding name="TransactedBinding" > <security mode="None" /> </binding> </netMsmqBinding> </bindings> </system.serviceModel> </configuration>El servicio para este ejemplo crea un enlace en
OrderProcessorService. Agregue una línea de código después de instanciar el enlace para establecer el modo de seguridad enNone.NetMsmqBinding msmqCallbackBinding = new NetMsmqBinding(); msmqCallbackBinding.Security.Mode = NetMsmqSecurityMode.None;Asegúrese de cambiar la configuración tanto en el servidor como en el cliente antes de ejecutar el ejemplo.
Nota:
Establecer
security modeenNonees equivalente a establecer MsmqAuthenticationMode, MsmqProtectionLevel oMessageseguridad enNone.