Compartir a través de


HttpCookieSession

El ejemplo HttpCookieSession demuestra cómo crear un canal de protocolo personalizado para usar cookies HTTP en la gestión de sesiones. Este canal permite la comunicación entre los servicios de Windows Communication Foundation (WCF) y los clientes ASMX o entre clientes WCF y servicios ASMX.

Cuando un cliente llama a un método web en un servicio web ASMX basado en sesión, el motor de ASP.NET hace lo siguiente:

  • Genera un identificador único (id. de sesión).

  • Genera el objeto de sesión y lo asocia al identificador único.

  • Agrega el identificador único a un encabezado de respuesta HTTP Set-Cookie y lo envía al cliente.

  • Identifica al cliente en llamadas posteriores en función del identificador de sesión que envía a él.

El cliente incluye este identificador de sesión en sus solicitudes posteriores al servidor. El servidor usa el identificador de sesión del cliente para cargar el objeto de sesión adecuado para el contexto HTTP actual.

Patrón de intercambio de mensajes del canal HttpCookieSession

En este ejemplo se habilitan sesiones para escenarios similares a ASMX. En la parte inferior de la pila de canales, tenemos el transporte HTTP que admite IRequestChannel y IReplyChannel. Es trabajo del canal proporcionar sesiones en los niveles más altos de la pila de canales. El ejemplo implementa dos canales, (IRequestSessionChannel y IReplySessionChannel) que admiten sesiones.

Canal de servicio

El ejemplo proporciona un canal de servicio en la HttpCookieReplySessionChannelListener clase . Esta clase implementa la interfaz IChannelListener y convierte el canal IReplyChannel desde una posición más baja en la pila de canales a un IReplySessionChannel. Este proceso se puede dividir en las siguientes partes:

  • Cuando se abre el agente de escucha del canal, acepta un canal interno desde su agente de escucha interno. Dado que éste es un agente de escucha de datagrama y la duración de un canal aceptado se desacopla de la duración del agente de escucha, podemos cerrar el agente de escucha interno y solo mantener el canal interno

                this.innerChannelListener.Open(timeoutHelper.RemainingTime());
    this.innerChannel = this.innerChannelListener.AcceptChannel(timeoutHelper.RemainingTime());
    this.innerChannel.Open(timeoutHelper.RemainingTime());
    this.innerChannelListener.Close(timeoutHelper.RemainingTime());
    
  • Cuando se completa el proceso abierto, configuramos un bucle de mensajes para recibir mensajes del canal interno.

    IAsyncResult result = BeginInnerReceiveRequest();
    if (result != null && result.CompletedSynchronously)
    {
       // do not block the user thread
       this.completeReceiveCallback ??= new WaitCallback(CompleteReceiveCallback);
       ThreadPool.QueueUserWorkItem(this.completeReceiveCallback, result);
    }
    
  • Cuando llega un mensaje, el canal del servicio examina el identificador de la sesión y demultiplexa en el canal de sesión adecuado. El agente de escucha del canal mantiene un diccionario que asigna los identificadores de la sesión a las instancias del canal de sesión.

    Dictionary<string, IReplySessionChannel> channelMapping;
    

La HttpCookieReplySessionChannel clase implementa IReplySessionChannel. Los niveles más altos de la pila de canales llaman al método ReceiveRequest para leer las solicitudes de esta sesión. Cada canal de sesión tiene una cola de mensajes privada rellenada por el canal de servicio.

InputQueue<RequestContext> requestQueue;

En el caso de que alguien llame al ReceiveRequest método y no haya ningún mensaje en la cola de mensajes, el canal espera una cantidad de tiempo especificada antes de cerrarse. Esto limpia los canales de sesión creados para clientes que no son WCF.

Usamos channelMapping para realizar el seguimiento de ReplySessionChannels, y no cerramos nuestro subyacente innerChannel hasta que se hayan cerrado todos los canales aceptados. De este modo HttpCookieReplySessionChannel , puede existir más allá de la duración de HttpCookieReplySessionChannelListener. Además, no nos tenemos que preocupar por el hecho de que el agente de escucha recopile elementos no utilizados debajo de nosotros porque los canales aceptados mantienen una referencia para su agente de escucha mediante la devolución de llamada OnClosed.

Canal de cliente

El canal de cliente correspondiente está en la HttpCookieSessionChannelFactory clase . Durante la creación del canal, el generador de canales ajusta el canal de solicitud interno con HttpCookieRequestSessionChannel. La HttpCookieRequestSessionChannel clase reenvía las llamadas al canal de solicitud subyacente. Cuando el cliente cierra el proxy, HttpCookieRequestSessionChannel envía un mensaje al servicio que indica que el canal se está cerrando. Así, la pila del canal del servicio puede apagar correctamente el canal de la sesión que está en uso.

Enlace y elemento de enlace

Después de crear el servicio y los canales de cliente, el siguiente paso es integrarlos en el entorno de ejecución de WCF. Los canales se exponen en WCF a través de enlaces y elementos de enlace. Un enlace consta de uno o varios elementos de enlace. WCF ofrece varios enlaces definidos por el sistema; por ejemplo, BasicHttpBinding o WSHttpBinding. La HttpCookieSessionBindingElement clase contiene la implementación del elemento de enlace. Invalida el agente de escucha del canal y los métodos de creación del generador de canales para crear las instancias del agente de escucha del canal y el generador de canales necesarios.

En el ejemplo se usan aserciones de directiva para la descripción del servicio. Esto permite al ejemplo publicar sus requisitos de canal en otros clientes que pueden utilizar el servicio. Por ejemplo, este elemento de enlace publica las aserciones de directiva para que los clientes potenciales sepan que admite sesiones. Dado que el ejemplo habilita la ExchangeTerminateMessage propiedad en la configuración del elemento de enlace, agrega las aserciones necesarias para mostrar que el servicio admite una acción adicional de intercambio de mensajes para finalizar la conversación de sesión. A continuación, los clientes pueden usar esta acción. El código WSDL siguiente muestra las aserciones de directiva creadas a partir de HttpCookieSessionBindingElement.

<wsp:Policy wsu:Id="HttpCookieSessionBinding_IWcfCookieSessionService_policy" xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsp:ExactlyOne>
<wsp:All>
<wspe:Utf816FFFECharacterEncoding xmlns:wspe="http://schemas.xmlsoap.org/ws/2004/09/policy/encoding"/>
<mhsc:httpSessionCookie xmlns:mhsc="http://samples.microsoft.com/wcf/mhsc/policy"/>
</wsp:All>
</wsp:ExactlyOne>
</wsp:Policy>

La HttpCookieSessionBinding clase es un enlace proporcionado por el sistema que usa el elemento de enlace descrito anteriormente.

Agregar el canal al sistema de configuración

El ejemplo proporciona dos clases que exponen el canal de ejemplo a través de la configuración. El primero es BindingElementExtensionElement para HttpCookieSessionBindingElement. La mayor parte de la implementación se delega en el HttpCookieSessionBindingConfigurationElement, que deriva de StandardBindingElement. HttpCookieSessionBindingConfigurationElement tiene propiedades que corresponden a las propiedades de HttpCookieSessionBindingElement.

Sección de extensión de elemento de enlace

La sección HttpCookieSessionBindingElementSection es un BindingElementExtensionElement que expone HttpCookieSessionBindingElement al sistema de configuración. Con algunas invalidaciones se define el nombre de la sección de configuración, el tipo del elemento de enlace y cómo crear el elemento de enlace. A continuación, podemos registrar la sección de extensión en un archivo de configuración de la siguiente manera:

<configuration>
    <system.serviceModel>
      <extensions>
        <bindingElementExtensions>
          <add name="httpCookieSession"
               type=
"Microsoft.ServiceModel.Samples.HttpCookieSessionBindingElementElement,
                    HttpCookieSessionExtension, Version=1.0.0.0,
                    Culture=neutral, PublicKeyToken=null"/>
        </bindingElementExtensions >
      </extensions>

      <bindings>
      <customBinding>
        <binding name="allowCookiesBinding">
          <textMessageEncoding messageVersion="Soap11WSAddressing10" />
          <httpCookieSession sessionTimeout="10" exchangeTerminateMessage="true" />
          <httpTransport allowCookies="true" />
        </binding>
      </customBinding>
      </bindings>
    </system.serviceModel>
</configuration>

Código de prueba

El código de prueba para usar este transporte de ejemplo está disponible en los directorios cliente y servicio. Se compone de dos pruebas: una utiliza un enlace con allowCookies establecido en true en el cliente. La segunda prueba habilita el apagado explícito (utilizando el intercambio de mensajes de finalización) en el enlace.

Al ejecutar el ejemplo, debería ver la siguiente salida:

Simple binding:
AddItem(10000,2): ItemCount=2
AddItem(10550,5): ItemCount=7
RemoveItem(10550,2): ItemCount=5
Items
10000, 2
10550, 3
Smart binding:
AddItem(10000,2): ItemCount=2
AddItem(10550,5): ItemCount=7
RemoveItem(10550,2): ItemCount=5
Items
10000, 2
10550, 3

Press <ENTER> to terminate client.

Para configurar, compilar y ejecutar el ejemplo

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

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