Compartir a través de


Demux personalizado

Este ejemplo muestra cómo los encabezados del mensaje de MSMQ pueden estar asignados a las operaciones del servicio diferentes para que los servicios Windows Communication Foundation (WCF) que utilizan MsmqIntegrationBinding no se limiten a utilizar una operación del servicio como se muestra en los ejemplos Message Queuing a Windows Communication Foundation y Windows Communication Foundation a Message Queuing.

El servicio de este ejemplo es una aplicación de consola autohospedada que permite observar el servicio que recibe los mensajes en cola.

El contrato de servicio es IOrderProcessor, y define un servicio unidireccional que es adecuado para usarse con colas.

[ServiceContract]
[KnownType(typeof(PurchaseOrder))]
[KnownType(typeof(String))]
public interface IOrderProcessor
{
    [OperationContract(IsOneWay = true, Name = "SubmitPurchaseOrder")]
    void SubmitPurchaseOrder(MsmqMessage<PurchaseOrder> msg);

    [OperationContract(IsOneWay = true, Name = "CancelPurchaseOrder")]
    void CancelPurchaseOrder(MsmqMessage<string> ponumber);
}

Un mensaje de MSMQ no tiene un encabezado Acción. No es posible asignar automáticamente los mensajes de MSMQ diferentes a los contratos de operación. Además, solo puede haber un contrato de operación. Para superar esta limitación, el servicio implementa el método SelectOperation de la interfaz IDispatchOperationSelector. El método SelectOperation permite al servicio asignar un encabezado determinado del mensaje a una operación del servicio determinada. En este ejemplo, el encabezado de etiqueta del mensaje está asignado a las operaciones del servicio. El parámetro Name del contrato de operación determina qué operación del servicio se debe enviar para una etiqueta del mensaje determinada. Por ejemplo, si el encabezado de etiqueta del mensaje contiene "SubmitPurchaseOrder", se invoca la operación de servicio de "SubmitPurchaseOrder."

public class OperationSelector : IDispatchOperationSelector
{
    public string SelectOperation(ref System.ServiceModel.Channels.Message message)
    {
        MsmqIntegrationMessageProperty property = MsmqIntegrationMessageProperty.Get(message);
        return property.Label;
    }
}

El servicio debe implementar el método ApplyDispatchBehavior de la interfaz IContractBehavior como se muestra en el código muestra siguiente. Esto aplica el OperationSelector personalizado a la expedición del marco de trabajo del servicio en tiempo de ejecución.

void IContractBehavior.ApplyDispatchBehavior(ContractDescription description, ServiceEndpoint endpoint, DispatchRuntime dispatch)
{
    dispatch.OperationSelector = new OperationSelector();
}

Un mensaje debe atravesar ContractFilter del distribuidor antes de llegar al OperationSelector. De forma predeterminada se rechaza un mensaje si su acción no se puede buscar en cualquier contrato implementado por el servicio. Para evitar esta comprobación, implementamos un IEndpointBehavior denominado MatchAllFilterBehavior, que permite a cualquier mensaje atravesar ContractFilter aplicando el MatchAllMessageFilter como sigue.

public void ApplyDispatchBehavior(ServiceEndpoint serviceEndpoint, EndpointDispatcher endpointDispatcher)
{
    endpointDispatcher.ContractFilter = new MatchAllMessageFilter();
}

Cuando el servicio recibe un mensaje, la operación del servicio adecuada se envía utilizando la información proporcionada por el encabezado de etiqueta. El cuerpo del mensaje se deserializa en un objeto PurchaseOrder, como se muestra en el código muestra siguiente.

[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = true)]
public void SubmitPurchaseOrder(MsmqMessage<PurchaseOrder> msg)
{
    PurchaseOrder po = (PurchaseOrder)msg.Body;
    Random statusIndexer = new Random();
    po.Status = (OrderStates)statusIndexer.Next(3);
    Console.WriteLine("Processing {0} ", po);
}

El servicio es autohospedado. Al utilizar el MSMQ, se debe crear la cola que se utiliza de antemano. Esto se puede hacer manualmente o a través de código. En este ejemplo, el servicio contiene el código para comprobar la existencia de la cola y crearla si no existe. El nombre de la cola se lee del archivo de configuración.

public static void Main()
{
    // Get MSMQ queue name from app settings in configuration
    string queueName = ConfigurationManager.AppSettings["orderQueueName"];

    // Create the transacted MSMQ queue if necessary.
    if (!MessageQueue.Exists(queueName))
        MessageQueue.Create(queueName, true);

    // Create a ServiceHost for the CalculatorService type.
    using (ServiceHost serviceHost = new ServiceHost(typeof(OrderProcessorService)))
    {               
        ServiceEndpoint endpoint = serviceHost.Description.Endpoints[0];
        endpoint.Behaviors.Add(new MatchAllFilterBehavior());

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

        // Close the ServiceHost to shutdown the service.
        serviceHost.Close();
    }
}

El nombre de cola de MSMQ se especifica en una sección appSettings del archivo de configuración.

ms752265.note(es-es,VS.100).gifNota:
El nombre de la cola utiliza un punto (.) para el equipo local y separadores con barra diagonal inversa en su ruta de acceso. La dirección de extremo de WCF especifica un esquema msmq.formatname y utiliza localhost para el equipo local. Lo que sigue al esquema es una dirección de cola con el formato apropiado según las instrucciones de direccionamiento del nombre de formato de MSMQ.

<appSettings>
    <!-- Use appSetting to configure the MSMQ queue name. -->
    <add key="queueName" value=".\private$\Orders" />
</appSettings>
ms752265.note(es-es,VS.100).gifNota:
Este ejemplo requiere la instalación de Message Queuing.

Inicie el servicio y ejecute el cliente.

El siguiente resultado se ve en el cliente.

Placed the order:Purchase Order: 28fc457a-1a56-4fe0-9dde-156965c21ed6
        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
Canceled the Order: 28fc457a-1a56-4fe0-9dde-156965c21ed6
Press <ENTER> to terminate client.

El resultado siguiente se debe ver en el servicio.

The service is ready.
Press <ENTER> to terminate service.
Processing Purchase Order: 28fc457a-1a56-4fe0-9dde-156965c21ed6
        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: Shipped
Purchase Order 28fc457a-1a56-4fe0-9dde-156965c21ed6 is canceled

Para configurar, compilar y ejecutar el ejemplo

  1. Asegúrese de realizar el procedimiento de Procedimiento de instalación única para los ejemplos de Windows Communication Foundation.

  2. Si se ejecuta el servicio primero, comprobará que la cola esté presente. Si la cola no está presente, el servicio creará una. Puede ejecutar primero el servicio para crear la cola, o puede crear una a través del administrador de cola de MSMQ. Siga estos pasos para crear una cola en Windows 2008.

    1. Abra el Administrador del servidor en Visual Studio 2010.

    2. Expanda la pestaña Características.

    3. Haga clic con el botón secundario en Cola de mensajes privados y seleccione Nuevo, Cola privada.

    4. Active la casilla Transaccional.

    5. Escriba ServiceModelSamplesTransacted como nombre de la nueva cola.

  3. Para compilar el código de la edición .NET de C# o Visual Basic de la solución, siga las instrucciones de Compilación de los ejemplos de Windows Communication Foundation.

  4. Para ejecutar el ejemplo en una configuración de equipos única o cruzada, siga las instrucciones de Running the Windows Communication Foundation Samples.

Para ejecutar el ejemplo en varios equipos

  1. Copie los archivos de programa del servicio de la carpeta \service\bin\, bajo la carpeta específica del lenguaje, al equipo del servicio.

  2. Copie los archivos de programa del cliente de la carpeta \client\bin\, bajo la carpeta específica del lenguaje, al equipo cliente.

  3. En el archivo Client.exe.config, cambie orderQueueName para especificar el nombre de equipo del servicio en lugar de ".".

  4. En el equipo del servicio, inicie Service.exe desde un símbolo del sistema.

  5. En el equipo cliente, inicie Client.exe desde un símbolo del sistema.

ms752265.Important(es-es,VS.100).gif Nota:
Puede que los ejemplos ya estén instalados en su equipo. Compruebe el siguiente directorio (valor predeterminado) antes de continuar.

<InstallDrive>: \WF_WCF_Samples

Si no existe este directorio, vaya a la página de ejemplos de Windows Communication Foundation (WCF) y Windows Workflow Foundation (WF) Samples para .NET Framework 4 para descargar todos los ejemplos de WF y Windows Communication Foundation (WCF). Este ejemplo se encuentra en el siguiente directorio.

<InstallDrive>:\WF_WCF_Samples\WCF\Basic\Binding\MSMQIntegration\CustomDemux

Vea también

Conceptos

Las colas en WCF

Otros recursos

Message Queuing