Compartir vía


Filtro de mensaje personalizado

El ejemplo MessageFilter muestra cómo reemplazar los filtros de mensajes que Windows Communication Foundation (WCF) utiliza para enviar mensajes a los puntos de conexión.

Nota

El procedimiento de instalación y las instrucciones de compilación de este ejemplo se encuentran al final de este tema.

Cuando el primer mensaje en un canal llega al servidor, el servidor debe determinar cual (en caso necesario) de los puntos de conexión asociados a ese URI debería recibir el mensaje. Los objetos MessageFilter adjuntados a EndpointDispatchercontrolan este proceso.

Cada extremo de un servicio tiene un EndpointDispatcherúnico. El EndpointDispatcher tiene ambos, unAddressFilter y un ContractFilter. La unión de estos dos filtros es el filtro de mensajes utilizado para ese punto de conexión.

De forma predeterminada, AddressFilter para un punto de conexión coincide con cualquier mensaje que se dirige a una dirección que coincide con el punto de conexión del servicioEndpointAddress. De forma predeterminada, el ContractFilter para un punto de conexión inspecciona la acción del mensaje entrante y coincide con cualquier mensaje con una acción que corresponde a una de las acciones de las operaciones del contrato del punto de conexión de servicio (solo las acciones IsInitiating=true están consideradas). Como resultado, de forma predeterminada, el filtro para un punto de conexión coincide solo si el encabezado del mensaje Para es EndpointAddress del punto de conexión y la acción del mensaje coincide con una de las acciones de la operación del punto de conexión.

Estos filtros se pueden cambiar utilizando un comportamiento. En el ejemplo, el servicio crea unIEndpointBehavior que reemplaza AddressFilter y ContractFilter en EndpointDispatcher:

class FilteringEndpointBehavior : IEndpointBehavior
{
    //...
}

Se definen dos filtros de la dirección:

// Matches any message whose To address contains the letter 'e'
class MatchEAddressFilter : MessageFilter { }
// Matches any message whose To address does not contain the letter 'e'
class MatchNoEAddressFilter : MessageFilter { }

FilteringEndpointBehavior se vuelve configurable y permite dos variaciones diferentes.

public class FilteringEndpointBehaviorExtension : BehaviorExtensionElement { }

La variación 1 solo coincide con direcciones que contienen una 'e' (pero este tiene cualquier Acción) mientras que la Variación 2 solo coincide con direcciones a las que les falta una 'e':

if (Variation == 1)
    return new FilteringEndpointBehavior(
        new MatchEAddressFilter(), new MatchAllMessageFilter());
else
    return new FilteringEndpointBehavior(
        new MatchNoEAddressFilter(), new MatchAllMessageFilter());

En el archivo de configuración, el servicio registra el nuevo comportamiento:

<extensions>
    <behaviorExtensions>
        <add name="filteringEndpointBehavior" type="Microsoft.ServiceModel.Samples.FilteringEndpointBehaviorExtension, service" />
    </behaviorExtensions>
</extensions>

A continuación, el servicio crea las configuraciones endpointBehavior para cada variación:

<endpointBehaviors>
    <behavior name="endpoint1">
        <filteringEndpointBehavior variation="1" />
    </behavior>
    <behavior name="endpoint2">
        <filteringEndpointBehavior variation="2" />
    </behavior>
</endpointBehaviors>

Finalmente, el extremo del servicio hace referencia a uno de behaviorConfigurations:

<endpoint address=""
        bindingConfiguration="ws"
        listenUri=""
        binding="wsHttpBinding"
        contract="Microsoft.ServiceModel.Samples.IHello"
        behaviorConfiguration="endpoint2" />

La implementación de la aplicación cliente es sencilla; crea dos canales al parámetro URI (pasando ese valor como el segundo (via) del servicio a CreateChannel(EndpointAddress) y envía un mensaje único en cada canal, pero utiliza diferentes direcciones de puntos de conexión para cada uno. Como resultado, los mensajes salientes del cliente tienen diferentes designaciones Para y el servidor responde correspondientemente, como se muestra en el resultado del cliente:

Sending message to urn:e...
Exception: The message with To 'urn:e' cannot be processed at the receiver, due to an AddressFilter mismatch at the EndpointDispatcher. Check that the sender and receiver's EndpointAddresses agree.

Sending message to urn:a...
Hello

Al intercambiar la variación en el archivo de configuración del servidor, el filtro se cambia y el cliente ve el comportamiento contrario (el mensaje a urn:e tiene éxito, mientras que el mensaje a urn:a produce un error).

<endpoint address=""
          bindingConfiguration="ws"
          listenUri=""
          binding="wsHttpBinding"
          contract="Microsoft.ServiceModel.Samples.IHello"
          behaviorConfiguration="endpoint1" />

Configurar, compilar y ejecutar el ejemplo

  1. Para compilar la solución, siga las instrucciones de Compilación de los ejemplos de Windows Communication Foundation.

  2. Para ejecutar el ejemplo en una configuración con un solo equipo o con varios, siga las instrucciones de Ejemplos de la ejecución de Windows Communication Foundation.

  3. Para ejecutar el ejemplo en una configuración con un solo equipo o con varios, siga las instrucciones de Ejemplos de la ejecución de Windows Communication Foundation y cambie la siguiente línea en Client.cs.

    Uri serviceVia = new Uri("http://localhost/ServiceModelSamples/service.svc");
    

    Reemplace el localhost con el nombre de servidor.

    Uri serviceVia = new Uri("http://servermachinename/ServiceModelSamples/service.svc");