Verwenden von Sitzungen

In WCF-Anwendungen (Windows Communication Foundation) verknüpft eine Sitzung eine Gruppe von Nachrichten zu einer Konversation. WCF-Sitzungen unterscheiden sich von dem in ASP.NET-Anwendungen verfügbaren Sitzungsobjekt, unterstützen andere Verhaltensweisen und werden auf andere Weise gesteuert. In diesem Thema werden die Features beschrieben, die Sitzungen in WCF-Anwendungen bieten, und Sie erfahren, wie Sie sie verwenden.

Sitzungen in Windows Communication Foundation-Anwendungen

Wenn ein Dienstvertrag angibt, dass er eine Sitzung benötigt, bedeutet dies, dass alle Aufrufe (das heißt der zugrunde liegende Nachrichtenaustausch, durch den die Aufrufe unterstützt werden) Teil derselben Konversation sein müssen. Falls in einem Vertrag angegeben wird, dass Sitzungen zwar erlaubt, aber nicht erforderlich sind, können Clients eine Verbindung herstellen und eine Sitzung aufbauen oder auch nicht. Wird eine Sitzung beendet und eine Nachricht über denselben Kanal gesendet, wird eine Ausnahme ausgelöst.

Bei WCF-Sitzungen gibt es die folgenden Hauptkonzepte:

  • Sie werden explizit von der aufrufenden Anwendung (dem WCF-Client) initiiert und beendet.

  • Die während einer Sitzung gesendeten Nachrichten werden in der Reihenfolge verarbeitet, in der sie empfangen wurden.

  • Durch Sitzungen wird eine Gruppe von Nachrichten zu einer Konversation zusammengefasst. Es sind verschiedene Korrelationstypen möglich. So werden zum Beispiel bei einem sitzungsbasierten Kanal Nachrichten auf Grundlage einer gemeinsamen Netzwerkverbindung zueinander in Beziehung gesetzt, bei einem anderen Kanal geschieht dies wiederum auf Grundlage eines gemeinsamen Tags im Nachrichtentext. Die Funktionen, die von der Sitzung abgeleitet werden können, sind abhängig von der Art der Korrelation.

  • Einer WCF-Sitzung ist kein allgemeiner Datenspeicher zugeordnet.

Falls Sie mit der System.Web.SessionState.HttpSessionState-Klasse und den von ihr bereitgestellten Funktionen in ASP.NET-Anwendungen vertraut sind, stellen Sie möglicherweise die folgenden Unterschiede zwischen dieser Art von Sitzung und WCF-Sitzungen fest:

  • ASP.NET-Sitzungen werden immer vom Server initiiert.

  • ASP.NET-Sitzungen sind implizit nicht sortiert.

  • ASP.NET-Sitzungen stellen einen allgemeinen Datenspeichermechanismus für Anforderungen bereit.

In diesem Thema wird Folgendes beschrieben:

  • Das Standardausführungsverhalten bei Verwendung sitzungsbasierter Bindungen auf Dienstmodellebene

  • Die Arten von Features, die die sitzungsbasierten, systemeigenen Bindungen von WCF bereitstellen.

  • Erstellen eines Vertrags, der eine Sitzungsanforderung deklariert

  • Verstehen und Steuern der Erstellung und Beendigung einer Sitzung sowie der Beziehung zwischen der Sitzung und der Dienstinstanz

Standardausführungsverhalten mit Sitzungen

Eine Bindung, die eine Sitzung zu initiieren versucht, wird als sitzungsbasierte Bindung bezeichnet. Dienstverträge geben an, dass sie sitzungsbasierte Bindungen erfordern, zulassen oder verweigern, indem sie die ServiceContractAttribute.SessionMode -Eigenschaft in der Dienstvertragschnittstelle (oder -klasse) auf einen der System.ServiceModel.SessionMode -Enumerationswerte festlegen. Standardmäßig ist der Wert dieser Eigenschaft Allowed. Das bedeutet, dass der Dienst die bereitgestellte Sitzung einrichtet und verwendet, wenn ein Client eine sitzungsbasierte Bindung mit einer WCF-Dienstimplementierung verwendet.

Wenn ein WCF-Dienst eine Clientsitzung akzeptiert, sind folgende Features standardmäßig aktiviert:

  1. Alle Aufrufe zwischen einem WCF-Clientobjekt werden von der gleichen Dienstinstanz verarbeitet.

  2. Andere sitzungsbasierte Bindungen stellen zusätzliche Funktionen bereit.

Vom System bereitgestellte Sitzungstypen

Eine sitzungsbasierte Bindung unterstützt die Standardzuordnung einer Dienstinstanz zu einer bestimmten Sitzung. Andere sitzungsbasierte Bindungen ermöglichen nicht nur die zuvor beschriebene sitzungsbasierte Instanziierungssteuerung, sondern unterstützen darüber hinaus andere Funktionen.

WCF stellt die folgenden Arten von sitzungsbasiertem Verhalten bereit:

Durch Festlegen der SessionMode -Eigenschaft wird nicht der vom Vertrag angeforderte Typ der Sitzung angegeben, sondern nur, dass eine Sitzung erforderlich ist.

Erstellen eines Vertrags, der eine Sitzung erfordert

Beim Erstellen eines Vertrags, der eine Sitzung erfordert, wird angegeben, dass die gesamte Gruppe von Vorgängen, die der Dienstvertrag deklariert, innerhalb derselben Sitzung ausgeführt werden muss und dass Nachrichten der Reihenfolge nach zugestellt werden müssen. Zum Bestätigen der Ebene der Sitzungsunterstützung, die ein Dienstvertrag erfordert, legen Sie die ServiceContractAttribute.SessionMode -Eigenschaft der Dienstvertragschnittstelle oder -klasse auf den Wert der System.ServiceModel.SessionMode -Enumeration fest. Damit geben Sie an, ob der Vertrag:

  • Eine Sitzung erfordert.

  • Es einem Client ermöglicht, eine Sitzung aufzubauen.

  • Eine Sitzung verhindert.

Durch Festlegen der SessionMode -Eigenschaft wird allerdings nicht der vom Vertrag angeforderte Typ des sitzungsbasierten Verhaltens angegeben. Sie weist WCF an, zur Laufzeit zu bestätigen, dass die konfigurierte Bindung (die den Kommunikationskanal erstellt) für den Dienst eine Sitzung einrichtet, keine Sitzung einrichtet oder eine Sitzung einrichten kann, wenn ein Dienst implementiert wird. Die Bindung kann diese Anforderung wiederum mit einem beliebigen, von ihr gewählten Typ eines sitzungsbasierten Verhaltens erfüllen – Sicherheit, Transport, Zuverlässigkeit oder eine Kombination daraus. Das genaue Verhalten hängt vom ausgewählten System.ServiceModel.SessionMode -Wert ab. Wenn die konfigurierte Bindung des Diensts nicht dem Wert von SessionModeentspricht, wird eine Ausnahme ausgelöst. Bindungen und die von ihnen erstellten Kanäle, die Sitzungen unterstützen, werden als sitzungsbasiert bezeichnet.

Der folgende Dienstvertrag gibt an, dass alle Vorgänge in ICalculatorSession innerhalb einer Sitzung ausgetauscht werden müssen. Mit Ausnahme der Equals -Methode gibt keiner der Vorgänge einen Wert an den Aufrufer zurück. Die Equals -Methode verwendet jedoch keine Parameter und kann daher nur einen Wert ungleich 0 (null) innerhalb der Sitzung zurückgeben, in der Daten bereits an die anderen Vorgänge übergeben wurden. Dieser Vertrag erfordert, dass eine Sitzung ordnungsgemäß funktioniert. Ist keine Sitzung einem bestimmten Client zugeordnet, kann die Dienstinstanz nicht ermitteln, welche Daten dieser Client bereits gesendet hat.

[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

Wenn ein Dienst eine Sitzung zulässt, wird die Sitzung aufgebaut und verwendet, wenn der Client eine Sitzung initiiert, andernfalls wird keine Sitzung aufgebaut.

Sitzungen und Dienstinstanzen

Wenn Sie das Standardinstanziierungsverhalten in WCF verwenden, werden alle Aufrufe zwischen einem WCF-Clientobjekt von der gleichen Dienstinstanz behandelt. Daher können Sie sich eine Sitzung auf Anwendungsebene so vorstellen, dass sie ein Anwendungsverhalten ermöglicht, das dem lokalen Aufrufverhalten ähnlich ist. Wenn Sie zum Beispiel ein lokales Objekt erstellen:

  • Wird ein Konstruktor aufgerufen.

  • Werden alle nachfolgenden Aufrufe an den WCF-Clientobjektverweis von der gleichen Objektinstanz verarbeitet.

  • Wird ein Destruktor aufgerufen, wenn der Objektverweis gelöscht wird.

Sitzungen ermöglichen ein ähnliches Verhalten zwischen Clients und Diensten, solange das Standardverhalten der Dienstinstanz verwendet wird. Wenn ein Dienstvertrag Sitzungen erfordert oder unterstützt, kann mindestens ein Vorgang durch Festlegen der IsInitiating -Eigenschaft und der IsTerminating -Eigenschaft zum Initiieren oder Beenden einer Sitzung angegeben werden.

Initiierungsvorgänge sind Vorgänge, die als erster Vorgang einer neuen Sitzung aufgerufen werden müssen. Nicht-Initiierungsvorgänge können nur aufgerufen werden, nachdem mindestens ein Initiierungsvorgang aufgerufen wurde. Sie können folglich eine Art Sitzungskonstruktor für den Dienst erstellen, indem Sie Initiierungsvorgänge deklarieren, die dazu gedacht sind, Eingaben von Clients anzunehmen, die sich für den Anfang der Dienstinstanz eignen. (Der Zustand ist jedoch der Sitzung zugeordnet, nicht dem Dienstobjekt.)

Beendigungsvorgängesind dagegen Vorgänge, die als letzte Nachricht in einer vorhandenen Sitzung aufgerufen werden müssen. Im Standardfall verwendet WCF das Dienstobjekt und seinen Kontext wieder, nachdem die Sitzung, der der Dienst zugeordnet war, geschlossen wurde. Sie können folglich eine Art Destruktor erstellen, indem Sie Beendigungsvorgänge deklarieren, die zum Ausführen einer Funktion gedacht sind, die sich für das Ende der Dienstinstanz eignet.

Hinweis

Das Standardverhalten ist lokalen Konstruktoren und Destruktoren ähnlich, aber eben nur ähnlich. Jeder WCF-Dienstvorgang kann ein Initiierungs- oder ein Beendigungsvorgang (oder beides) sein. Außerdem können Initiierungsvorgänge im Standardfall beliebig oft in einer beliebigen Reihenfolge aufgerufen werden, nachdem der erste Vorgang aufgerufen wurde. Es werden keine zusätzlichen Sitzungen erstellt, sobald die Sitzung aufgebaut und einer Instanz zugeordnet wurde, es sei denn, Sie steuern die Lebensdauer der Dienstinstanz explizit (durch Bearbeiten des System.ServiceModel.InstanceContext -Objekts). Der Zustand wird schließlich der Sitzung zugeordnet, nicht dem Dienstobjekt.

Der im vorhergehenden Beispiel verwendete ICalculatorSession-Vertrag erfordert beispielsweise, dass das WCF-Clientobjekt den Clear-Vorgang vor allen anderen Vorgängen aufruft und dass die Sitzungen mit diesem WCF-Clientobjekt beendet werden, wenn der Equals-Vorgang aufgerufen wird. Das folgende Codebeispiel zeigt einen Vertrag, der diese Anforderungen erzwingt. Clear muss zuerst aufgerufen werden, um eine Sitzung zu initiieren. Diese Sitzung endet, wenn Equals aufgerufen wird.

[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

Dienste starten keine Sitzungen mit Clients. In WCF-Clientanwendungen gibt es eine direkte Beziehung zwischen der Lebensdauer des sitzungsbasierten Kanals und der Lebensdauer der Sitzung. Aus diesem Grund erstellen Clients neue Sitzungen, indem sie neue sitzungsbasierte Kanäle erstellen, und beenden bestehende Sitzungen, indem sie sitzungsbasierte Kanäle ordnungsgemäß schließen. Ein Client startet eine Sitzung mit einem Dienstendpunkt, indem er einen der folgenden Vorgänge aufruft:

Ein Client beendet eine Sitzung in der Regel mit einem Dienstendpunkt, indem er einen der folgenden Vorgänge aufruft:

  • ICommunicationObject.Close auf dem Kanal, das durch einen Aufruf an ChannelFactory<TChannel>.CreateChannelzurückgegeben wurde.

  • ClientBase<TChannel>.Close für das WCF-Clientobjekt, das von „Svcutil.exe“ generiert wurde.

  • Einen Beendigungsvorgang für einen der Typen eines WCF-Clientobjekts. (Standardmäßig sind Vorgänge nie Beendigungsvorgänge. Der Vertrag muss einen Beendigungsvorgang explizit angeben.) Wenn der erste Vorgang aufgerufen wird, öffnet das WCF-Clientobjekt den Kanal automatisch und initiiert eine Sitzung.

Beispiele finden Sie unter How to: Create a Service That Requires Sessions sowie unter Default Service Behavior und Instancing .

Weitere Informationen zu Clients und Sitzungen finden Sie unter Zugreifen auf Dienste mithilfe eines Clients.

Interaktion von Sitzungen und InstanceContext-Einstellungen

Zwischen der SessionMode -Enumeration in einem Vertrag und der ServiceBehaviorAttribute.InstanceContextMode -Eigenschaft gibt es eine Interaktion, durch die die Zuordnung zwischen Kanälen und bestimmten Dienstobjekten gesteuert wird. Weitere Informationen finden Sie unter Sitzungen, Instanziierung und Parallelität.

Freigeben von InstanceContext-Objekten

Sie können auch steuern, welcher sitzungsbasierte Kanal oder Aufruf welchem InstanceContext -Objekt zugeordnet wird, indem Sie diese Zuordnung selbst vornehmen.

Sitzungen und Streaming

Wenn Sie eine große Datenmenge übertragen müssen, ist der Streamingübertragungsmodus in WCF eine praktische Alternative zum Standardverhalten, bei dem vollständige Nachrichten im Arbeitsspeicher gepuffert und verarbeitet werden. Möglicherweise tritt beim Streaming von Aufrufen mit einer sitzungsbasierten Bindung ein unerwartetes Verhalten auf. Alle Streamingaufrufe erfolgen über einen einzigen Kanal (den Datagrammkanal), der keine Sitzungen unterstützt, selbst wenn die verwendete Bindung für die Verwendung von Sitzungen konfiguriert ist. Wenn mehrere Clients über eine sitzungsbasierte Bindung Streamingaufrufe an das gleiche Dienstobjekt senden und der Parallelitätsmodus des Dienstobjekts auf "single" und sein Instanzkontextmodus auf PerSessionfestgelegt ist, müssen alle Aufrufe den Datagrammkanal passieren, sodass immer nur jeweils ein Aufruf verarbeitet wird. Bei einem oder mehreren Clients kommt es dabei unter Umständen zu einem Timeout. Sie können dieses Problem umgehen, indem Sie entweder den Instanzkontextmodus (InstanceContextMode) des Dienstobjekts auf PerCall oder die Parallelität auf „multiple“ festlegen.

Hinweis

MaxConcurrentSessions hat in diesem Fall keine Auswirkungen, da nur eine Sitzung verfügbar ist.

Siehe auch