Uso de sesiones

En las aplicaciones Windows Communication Foundation (WCF), una sesión pone en correlación un grupo de mensajes en una conversación. Las sesiones WCF son diferentes al objeto de sesión disponible en las aplicaciones ASP.NET, admiten diferentes comportamientos y se controlan de formas diferentes. En este tema se describen las características que habilitan las sesiones en las aplicaciones WCF y cómo se usan.

Sesiones en aplicaciones de Windows Communication Foundation

Cuando un contrato de servicio especifica que requiere una sesión, ese contrato está especificando que todas las llamadas (es decir, los intercambios de mensajes subyacentes que admiten las llamadas) deben formar parte de la misma conversación. Si un contrato especifica que admite sesiones pero no requiere una, los clientes pueden conectarse y establecer o no una sesión. Si la sesión finaliza y se envía un mensaje se envía a través del mismo canal, se produce una excepción.

Las sesiones WCF tienen las siguientes características conceptuales principales:

  • La aplicación (el cliente WCF) que realiza la llamada inicia y finaliza explícitamente las sesiones.

  • Los mensajes entregados durante una sesión se procesan en el orden de recepción.

  • Las sesiones correlacionan un grupo de mensajes en una conversación. Son posibles distintos tipos de correlaciones. Por ejemplo, un canal basado en sesión puede correlacionar mensajes basados en una conexión de red compartida, mientras que otro canal basado en sesión puede correlacionar mensajes basados en una etiqueta compartida en el cuerpo del mensaje. Las características que se pueden derivar a partir de la sesión dependen de la naturaleza de la correlación.

  • No hay ningún almacén de datos general asociado a una sesión de WCF.

Si está familiarizado con la clase System.Web.SessionState.HttpSessionState en aplicaciones ASP.NET y la funcionalidad que proporciona, puede que observe las siguientes diferencias entre ese tipo de sesión y las sesiones de WCF:

  • Las sesiones de ASP.NET siempre se inician en el servidor.

  • Las sesiones de ASP.NET están implícitamente desordenadas.

  • Las sesiones ASP.NET proporcionan un mecanismo de almacenamiento de datos general entre solicitudes.

En este tema se describe:

  • El comportamiento de ejecución predeterminado al utilizar enlaces basados en sesión en el nivel de modelo de servicio.

  • Los tipos de características que proporcionan los enlaces WCF basados en sesión que proporciona el sistema.

  • Cómo crear un contrato que declare un requisito de sesión.

  • Cómo entender y controlar la creación y finalización de la sesión y la relación de la sesión con la instancia del servicio.

Comportamiento de ejecución predeterminado mediante sesiones

Un enlace que intenta iniciar una sesión se denomina enlace basado en sesión . Los contratos de servicio especifican que requieren, permiten o rechazan enlaces basados en sesión estableciendo la propiedad ServiceContractAttribute.SessionMode en la interfaz (o clase) del contrato de servicio en uno de los valores de enumeración del System.ServiceModel.SessionMode . El valor de esta propiedad es Allowed de forma predeterminada, lo que significa que si un cliente usa un enlace basado en sesión con una implementación de servicio WCF, el servicio establece y usa la sesión proporcionada.

Cuando un servicio WCF acepta una sesión de cliente, se habilitan las siguientes características de forma predeterminada:

  1. Todas las llamadas entre un objeto de cliente WCF las controla la misma instancia de servicio.

  2. Los distintos enlaces basados en sesión proporcionan características adicionales.

Tipos de sesión proporcionados por el sistema

Un enlace basado en sesión admite la asociación predeterminada de una instancia de servicio con una sesión determinada. Sin embargo, diferentes enlaces basados en sesión admiten distintas características además de habilitar el control de creación de instancias basadas en sesión descrito anteriormente.

WCF proporciona los siguientes tipos de comportamiento de aplicación basado en sesión:

Establecer la propiedad SessionMode no especifica el tipo de sesión que el contrato requiere, solo que requiere uno.

Creación de un contrato que requiere una sesión

La creación de un contrato que requiere una sesión hace que el grupo de operaciones que declara el contrato de servicio deba ejecutarse dentro de la misma sesión y que los mensajes deban entregarse en orden. Para validar el nivel de compatibilidad de la sesión que requiere un contrato de servicio, establezca la propiedad ServiceContractAttribute.SessionMode de su clase o interfaz de contrato de servicio en el valor de la enumeración System.ServiceModel.SessionMode para especificar si el contrato:

  • Requiere una sesión.

  • Permite a un cliente establecer una sesión.

  • Prohíbe una sesión.

Establecer la propiedad SessionMode no especifica, sin embargo, el tipo de comportamiento basado en sesión que requiere el contrato. Indica a WCF que confirme en tiempo de ejecución que el enlace configurado (que crea el canal de comunicación) para el servicio establece, no establece o puede establecer una sesión cuando se implementa un servicio. De nuevo, el enlace puede satisfacer ese requisito con cualquier tipo de comportamiento basado en sesión que elija: seguridad, transporte, confiable o alguna combinación. El comportamiento exacto depende del valor de la enumeración System.ServiceModel.SessionMode seleccionada. Si el enlace configurado del servicio no cumple con el valor de SessionMode, se produce una excepción. Los enlaces, y los canales que esos enlaces crean, que admiten sesiones se dice que son basados en sesión.

El siguiente contrato de servicio especifica que todas las operaciones de la ICalculatorSession se deben intercambiar dentro de una sesión. Ninguna de las operaciones devuelve un valor al llamador, salvo el método Equals . Sin embargo, el método Equals no toma ningún parámetro y, por consiguiente, solo puede devolver un valor distinto de cero dentro de una sesión en la que los datos ya se han pasado a otras operaciones. Este contrato requiere que una sesión funcione correctamente. Si no hay una sesión asociada a un cliente concreto, la instancia del servicio no tiene forma de saber qué datos anteriores ha enviado este cliente.

[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples", SessionMode=SessionMode.Required)]
public interface ICalculatorSession
{
    [OperationContract(IsOneWay=true)]
    void Clear();
    [OperationContract(IsOneWay = true)]
    void AddTo(double n);
    [OperationContract(IsOneWay = true)]
    void SubtractFrom(double n);
    [OperationContract(IsOneWay = true)]
    void MultiplyBy(double n);
    [OperationContract(IsOneWay = true)]
    void DivideBy(double n);
    [OperationContract]
    double Equals();
}
<ServiceContract(Namespace:="http://Microsoft.ServiceModel.Samples", SessionMode:=SessionMode.Required)> _
Public Interface ICalculatorSession

    <OperationContract(IsOneWay:=True)> _
    Sub Clear()
    <OperationContract(IsOneWay:=True)> _
    Sub AddTo(ByVal n As Double)
    <OperationContract(IsOneWay:=True)> _
    Sub SubtractFrom(ByVal n As Double)
    <OperationContract(IsOneWay:=True)> _
    Sub MultiplyBy(ByVal n As Double)
    <OperationContract(IsOneWay:=True)> _
    Sub DivideBy(ByVal n As Double)
    <OperationContract()> _
    Function Equal() As Double
End Interface

Si un servicio permite una sesión, se establece una sesión y se utiliza si el cliente inicia una; de lo contrario, no se establece ninguna sesión.

Sesiones e instancias de servicios

Si usa el comportamiento de creación de instancias predeterminado en WCF, la misma instancia de servicio controlará todas las llamadas entre un objeto de cliente WCF. Por consiguiente, en el nivel de aplicación, puede considerar una sesión como la habilitación de un comportamiento de aplicación similar al comportamiento de la llamada local. Por ejemplo, al crear un objeto local:

  • Se llama a un constructor.

  • La misma instancia de objeto procesa todas las llamadas subsiguientes que se realizan a la referencia de objeto de cliente WCF.

  • Se llama a un destructor cuando se destruye la referencia del objeto.

Las sesiones habilitan un comportamiento similar entre clientes y servicios, siempre que se utilice el comportamiento de instancia de servicio predeterminado. Si un contrato de servicio requiere o admite sesiones, se pueden marcar una o más operaciones del contrato como que inician o finalizan una sesión estableciendo las propiedades IsInitiating y IsTerminating .

Lasoperaciones de inicio son aquellas que deben llamarse como la primera operación de una nueva sesión. Las operaciones que no son de inicio sólo pueden llamarse después de que se haya llamado, al menos, a una operación de inicio. Puede crear, por consiguiente, un tipo de constructor de sesión para su servicio mediante la declaración de operaciones de inicio diseñadas para tomar entradas de clientes apropiadas para el inicio de la instancia de servicio. (Sin embargo, el estado se asocia a la sesión, y no el objeto de servicio).

Lasoperaciones de finalización, por el contrario, son aquellas a las que se debe llamar como el último mensaje de una sesión existente. En el caso predeterminado, WCF recicla el objeto de servicio y su contexto después de que se cierre la sesión a la que se asoció el servicio. Por consiguiente, puede crear un tipo de destructor declarando operaciones de finalización diseñadas para realizar una función adecuada al final de la instancia de servicio.

Nota

Aunque el comportamiento predeterminado se parece algo a los constructores y destructores locales, solo es eso, un parecido. Cualquier operación de servicio WCF puede ser una operación de inicio o finalización o bien ambas al mismo tiempo. Además, en el caso predeterminado, las operaciones de inicio pueden llamarse cualquier número de veces en cualquier orden; no se crean sesiones adicionales una vez que se establezca la sesión y se asocie a una instancia, a menos que controle explícitamente la duración de la instancia del servicio (manipulando el objeto System.ServiceModel.InstanceContext ). Finalmente, el estado se asocia a la sesión y no al objeto de servicio.

Por ejemplo, el contrato ICalculatorSession que se usa en el ejemplo anterior necesita que el objeto de cliente WCF llame primero a la operación Clear antes que a cualquier otra y que la sesión con este objeto de cliente WCF debe finalizar cuando llame a la operación Equals. El ejemplo de código siguiente muestra un contrato que aplica estos requisitos. Se debe llamar primero aClear para iniciar una sesión y esa sesión finaliza cuando se llama a Equals .

[ServiceContract(Namespace="http://Microsoft.ServiceModel.Samples", SessionMode=SessionMode.Required)]
public interface ICalculatorSession
{
    [OperationContract(IsOneWay=true, IsInitiating=true, IsTerminating=false)]
    void Clear();
    [OperationContract(IsOneWay = true, IsInitiating = false, IsTerminating = false)]
    void AddTo(double n);
    [OperationContract(IsOneWay = true, IsInitiating = false, IsTerminating = false)]
    void SubtractFrom(double n);
    [OperationContract(IsOneWay = true, IsInitiating = false, IsTerminating = false)]
    void MultiplyBy(double n);
    [OperationContract(IsOneWay = true, IsInitiating = false, IsTerminating = false)]
    void DivideBy(double n);
    [OperationContract(IsInitiating = false, IsTerminating = true)]
    double Equals();
}
<ServiceContract(Namespace:="http://Microsoft.ServiceModel.Samples", SessionMode:=SessionMode.Required)> _
Public Interface ICalculatorSession

    <OperationContract(IsOneWay:=True, IsInitiating:=True, IsTerminating:=False)> _
    Sub Clear()
    <OperationContract(IsOneWay:=True, IsInitiating:=False, IsTerminating:=False)> _
    Sub AddTo(ByVal n As Double)
    <OperationContract(IsOneWay:=True, IsInitiating:=False, IsTerminating:=False)> _
    Sub SubtractFrom(ByVal n As Double)
    <OperationContract(IsOneWay:=True, IsInitiating:=False, IsTerminating:=False)> _
    Sub MultiplyBy(ByVal n As Double)
    <OperationContract(IsOneWay:=True, IsInitiating:=False, IsTerminating:=False)> _
    Sub DivideBy(ByVal n As Double)
    <OperationContract(IsInitiating:=False, IsTerminating:=True)> _
    Function Equal() As Double
End Interface

Los servicios no inician sesiones con clientes. En aplicaciones cliente WCF, existe una relación directa entre la duración del canal basado en sesión y la duración de la propia sesión. Como tal, los clientes crean nuevas sesiones creando nuevos canales basados en sesión y acaban con las sesiones existentes cerrando correctamente los canales basados en sesión. Un cliente inicia una sesión con un extremo de servicio llamando a uno de los siguientes métodos:

Por lo general, un cliente finaliza una sesión con un extremo de servicio llamando a uno de los siguientes métodos:

  • ICommunicationObject.Close en el canal devuelto por una llamada a ChannelFactory<TChannel>.CreateChannel.

  • ClientBase<TChannel>.Close en el objeto de cliente WCF que genera Svcutil.exe.

  • Una operación de finalización en cualquier tipo de objeto de cliente WCF (ninguna operación es de finalización de forma predeterminada; el contrato debe especificar explícitamente una operación de finalización). Cuando se llama a la primera operación, el objeto de cliente WCF abre de forma automática el canal e inicia una sesión.

Para obtener ejemplos, consulte How to: Create a Service That Requires Sessions , así como los ejemplos de Default Service Behavior y Instancing .

Para obtener más información sobre clientes y sesiones, consulte Acceso a servicios mediante un cliente WCF.

Las sesiones interactúan con la configuración de InstanceContext

Hay una interacción entre la enumeración de SessionMode en un contrato y la propiedad ServiceBehaviorAttribute.InstanceContextMode , que controla la asociación entre canales y objetos de servicio concretos. Para obtener más información, consulte Sesiones, creación de instancias y simultaneidad.

Uso compartido de objetos InstanceContext

También puede controlar qué canal basado en sesión o llamada se asocia a qué objeto InstanceContext realizando esa asociación usted mismo.

Sesiones y transmisión por secuencias

Cuando tiene una gran cantidad de datos para transferir, el modo de transferencia de streaming en WCF es una alternativa factible al comportamiento predeterminado de almacenamiento en búfer y procesamiento de mensajes en memoria en su totalidad. Puede obtener un comportamiento inesperado al transmitir mediante secuencias las llamadas con un enlace basado en sesión. Todas las llamadas de transferencias por secuencias se realizan a través de un canal único (el canal del datagrama) que no admite sesiones incluso si el enlace utilizado esté configurado para utilizar sesiones. Si varios clientes realizan llamadas de transferencias por secuencias al mismo objeto de servicio sobre un enlace basado en sesión y el modo de simultaneidad del objeto de servicio se ha establecido como Single y su modo de contexto de instancia está establecido en PerSession, todas las llamadas deben pasar por el canal de datagrama y, por lo tanto, solo se procesa una llamada al mismo tiempo. Uno o varios clientes pueden agotar el tiempo de espera. Para solucionar este problema, puede establecer el InstanceContextMode del objeto de servicio en PerCall o Simultaneidad en varios.

Nota

MaxConcurrentSessions no influye en este caso porque solo hay una "sesión" disponible.

Consulte también