Interceptador de mensajes personalizados

El ejemplo MessageInterceptor muestra el uso del modelo de extensibilidad del canal. En particular, muestra cómo implementar un elemento de enlace personalizado que crea generadores de canales y agentes de escucha de canales para interceptar todos los mensajes entrantes y salientes en un punto concreto en la pila de tiempo de ejecución. El ejemplo también incluye un cliente y un servidor que muestran el uso de estos generadores personalizados.

En este ejemplo, el cliente y el servicio son programas de consola (.exe). El cliente y el servicio hacen uso de una biblioteca común (.dll) que contiene el elemento de enlace personalizado y sus objetos en tiempo de ejecución asociados.

Nota

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

El ejemplo describe el procedimiento recomendado para crear un canal superpuesto personalizado en Windows Communication Foundation (WCF), utilizando el marco del canal y los siguientes procedimientos recomendados de WCF. Los pasos para crear un canal superpuesto personalizado son los siguientes:

  1. Decida cuál de las formas del canal admitirá el generador de canales y el agente de escucha del canal.

  2. Cree un generador de canales y un agente de escucha del canal que admita las formas del canal.

  3. Agregue un elemento de enlace que añada el canal superpuesto personalizado a una pila de canales.

  4. Agregue una sección de extensión de elemento de enlace para exponer el nuevo elemento de enlace al sistema de configuración.

Formas del canal

El primer paso para escribir un canal superpuesto personalizado es decidir qué formas son necesarias para el canal. Para nuestro inspector de mensajes, admitimos cualquier forma que admita el nivel debajo de nosotros (por ejemplo, si la capa debajo de nosotros puede compilar IOutputChannel y IDuplexSessionChannel, también exponemos IOutputChannel y IDuplexSessionChannel).

Generador de canales y de agentes de escucha

El paso siguiente para escribir un canal superpuesto personalizado es crear una implementación de IChannelFactory para los canales de cliente y de IChannelListener para los canales de servicio.

Estas clases escogen un generador y un agente de escucha internos y delegan todas las llamadas excepto OnCreateChannel y OnAcceptChannel al generador y agente de escucha internos.

class InterceptingChannelFactory<TChannel> : ChannelFactoryBase<TChannel>
{
    //...
}

class InterceptingChannelListener<TChannel> : ListenerFactoryBase<TChannel>
{
    //...
}

Adición de un elemento de enlace

El ejemplo define un elemento de enlace personalizado: InterceptingBindingElement. InterceptingBindingElement toma un ChannelMessageInterceptor como una entrada y utiliza este ChannelMessageInterceptor para manipular los mensajes que lo atraviesan. Ésta es la única clase que debe ser pública. El generador, agente de escucha y canales pueden ser implementaciones internas de las interfaces en tiempo de ejecución públicas.

public class InterceptingBindingElement : BindingElement
{
}

Agregación de la compatibilidad de configuración

Para integrar con la configuración de enlace, la biblioteca define un controlador de la sección de configuración como una sección de extensión de elemento de enlace. Los archivos de configuración del servidor y el cliente deben registrar la extensión del elemento de enlace con el sistema de configuración. Los implementadores que desean exponer su elemento de enlace al sistema de configuración pueden derivar de esta clase.

public abstract class InterceptingElement : BindingElementExtensionElement
{
    //...
}

Adición de directivas

Para integrar con nuestro sistema de directivas, InterceptingBindingElement implementa IPolicyExportExtension para señalar que deberíamos participar en la generación de directivas. Para permitir importar la directiva en un cliente generado, el usuario puede registrar una clase derivada de InterceptingBindingElementImporter e invalidar CreateMessageInterceptor() para generar su clase ChannelMessageInterceptor habilitada por la directiva.

Ejemplo: inspector de mensajes que pueden quitarse

En este ejemplo se incluye una implementación de ejemplo de ChannelMessageInspector que quita mensajes.

class DroppingServerElement : InterceptingElement
{
    protected override ChannelMessageInterceptor CreateMessageInterceptor()
    {
        return new DroppingServerInterceptor();
    }
}

Puede tener acceso a ella desde la configuración de la manera siguiente:

<configuration>
    ...
    <system.serviceModel>
        ...
        <extensions>
            <bindingElementExtensions>
                <add name="droppingInterceptor"
                   type=
          "Microsoft.ServiceModel.Samples.DroppingServerElement, library"/>
            </bindingElementExtensions>
        </extensions>
    </system.serviceModel>
</configuration>

El cliente y servidor usan esta sección de configuración que se acaba de crear para insertar los generadores personalizados en el nivel más bajo de sus pilas de canales en el tiempo de ejecución (por encima del nivel de transporte).

<customBinding>
  <binding name="sampleBinding">
    <droppingInterceptor/>
    <httpTransport/>
  </binding>
</customBinding>

El cliente utiliza la biblioteca MessageInterceptor para agregar un encabezado personalizado a mensajes con número par. Por otra parte, el servicio utiliza la biblioteca MessageInterceptor para colocar cualquier mensaje que no tenga este encabezado especial.

Debería ver el siguiente resultado del cliente después de ejecutar primero el servicio y después el cliente.

Reporting the next 10 wind speed
100 kph
Server dropped a message.
90 kph
80 kph
Server dropped a message.
70 kph
60 kph
Server dropped a message.
50 kph
40 kph
Server dropped a message.
30 kph
20 kph
Server dropped a message.
10 kph
Press ENTER to shut down client

El cliente informa sobre 10 velocidades de viento diferentes para el servicio, pero solo marca la mitad con el encabezado especial.

En el servicio, debería ver el resultado siguiente:

Press ENTER to exit.
Dangerous wind detected! Reported speed (90) is greater than 64 kph.
Dangerous wind detected! Reported speed (70) is greater than 64 kph.
5 wind speed reports have been received.

Configurar, compilar y ejecutar el ejemplo

  1. Instale ASP.NET 4.0 con el siguiente comando.

    %windir%\Microsoft.NET\Framework\v4.0.XXXXX\aspnet_regiis.exe /i /enable
    
  2. Asegúrese de que ha realizado el procedimiento de instalación única para los ejemplos de Windows Communication Foundation.

  3. Para compilar la solución, siga las instrucciones que se indican en Compilación de los ejemplos de Windows Communication Foundation.

  4. 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.

  5. Ejecute primero Service.exe, a continuación, ejecute Client.exe e inspeccione ambas ventanas de la consola para ver el resultado.