Compartir a través de


Demux personalizado

Download sample

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 Windows Communication Foundation a Message Queue Server y Message Queue Server a Windows Communication Foundation.

El servicio en este ejemplo es una aplicación de consola hospedada en sí mismaque 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, sólo 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 se hospeda en sí mismo. 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.

Nota

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 de msmq.formatname y utiliza el "host local" para el equipo local. Lo que sigue al esquema es una dirección de la cola con un formato apropiado según el nombre de formato de MSMQ que direcciona las instrucciones.

<appSettings>
    <!-- Use appSetting to configure the MSMQ queue name. -->
    <add key="queueName" value=".\private$\Orders" />
</appSettings>

Nota

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
Cancelled 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 cancelled

Para configurar, generar y ejecutar el ejemplo

  1. Asegúrese de que ha realizado el Procedimiento de instalación único para ejemplos de Windows Communication Foundation.

  2. Para generar el código C# o Visual Basic .NET Edition de la solución, siga las instrucciones de Generación de ejemplos de Windows Communication Foundation.

  3. Para ejecutar el ejemplo en una configuración de equipos única o cruzada, siga las instrucciones de Ejecución de ejemplos de Windows Communication Foundation.

Para ejecutar el ejemplo en varios equipos

  1. Copie los archivos de programa de 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 del 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 el símbolo del sistema.

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

Consulte también

Otros recursos

Queuing in WCF
Message Queue Server

Footer image

Copyright © 2007 Microsoft Corporation. Reservados todos los derechos.