Verwenden von Sitzungen
In Windows Communication Foundation (WCF)-Anwendungen verknüpft eine Sitzung eine Gruppe von Nachrichten zu einer Konversation. WCF-Sitzungen sind anders als das in ASP.NET-Anwendungen verfügbare Sitzungsobjekt, unterstützen andere Verhaltensweisen und werden auf andere Weise gesteuert. In diesem Thema werden die Funktionen, die Sitzungen in WCF-Anwendungen ermöglichen, beschrieben und deren Verwendung erläutert.
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 finden sich 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, fallen Ihnen möglicherweise die folgenden Unterschiede zwischen dieser Art von Sitzung und einer WCF-Sitzung auf:
ASP.NET-Sitzungen werden immer vom Server initiiert.
ASP.NET-Sitzungen sind implizit nicht sortiert.
ASP.NET-Sitzungen stellen einen allgemeinen Datenspeicher für Anforderungen bereit.
Dieses Thema beschreibt Folgendes:
Das Standardausführungsverhalten bei Verwendung sitzungsbasierter Bindungen auf Dienstmodellebene
Die Funktionstypen, 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 System.ServiceModel.ServiceContractAttribute.SessionMode-Eigenschaft in der Dienstvertragschnittstelle (oder -klasse) auf einen der System.ServiceModel.SessionMode-Enumerationswerte festlegen. Standardmäßig ist der Wert dieser Eigenschaft Allowed. Dies bedeutet, dass der Dienst die bereitgestellte Sitzung aufbaut und verwendet, wenn ein Client eine sitzungsbasierte Bindung mit einer WCF-Dienstimplementierung verwendet.
Wenn ein WCF-Dienst eine Clientsitzung akzeptiert, werden die folgenden Funktionen standardmäßig aktiviert:
Alle Aufrufe zwischen einem WCF-Clientobjekt werden von der gleichen Dienstinstanz verarbeitet.
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 Typen eines sitzungsbasierten Verhaltens bereit:
System.ServiceModel.Channels.SecurityBindingElement unterstützt sicherheitsbasierte Sitzungen, bei denen sich beide Kommunikationspartner auf eine bestimmte sichere Konversation verständigen. Weitere Informationen finden Sie unter Sichern von Diensten. Die System.ServiceModel.WSHttpBinding-Bindung, bei der sowohl Sicherheitssitzungen als auch zuverlässige Sitzungen unterstützt werden, verwendet z. B. standardmäßig nur eine sichere Sitzung, die Nachrichten digital verschlüsselt und signiert.
Die System.ServiceModel.NetTcpBinding-Bindung unterstützt TCP/IP-basierte Sitzungen, um sicherzustellen, dass alle Nachrichten von der Verbindung auf Socketebene miteinander in Beziehung gesetzt werden.
Das System.ServiceModel.Channels.ReliableSessionBindingElement-Element, das die WS-ReliableMessaging-Spezifikation implementiert, bietet Unterstützung für zuverlässige Sitzungen, in denen Nachrichten so konfiguriert werden können, dass sie der Reihenfolge nach und genau einmal zugestellt werden, sodass der Empfang von Nachrichten sichergestellt wird, auch wenn sich diese während der Konversation durch mehrere Knoten bewegen. Weitere Informationen finden Sie unter Zuverlässige Sitzungen.
Die System.ServiceModel.NetMsmqBinding-Bindung stellt MSMQ-Datagrammsitzungen bereit. Weitere Informationen finden Sie unter Warteschlangen in Windows Communication Foundation.
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 System.ServiceModel.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 aufbaut, keine Sitzung aufbaut oder eine Sitzung aufbauen 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 SessionMode entspricht, 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)> _
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
[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();
}
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änge sind 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, die dem 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 gleichzeitig 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 z. B., dass das WCF-Clientobjekt den Clear
-Vorgang vor allen anderen Vorgängen aufruft und dass die Sitzungen mit diesem WCF-Clientobjekt beendet werden sollen, wenn der Equals
-Vorgang aufgerufen wird. Das folgende Codebeispiel zeigt einen Vertrag, der diese Anforderungen durchsetzt. 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)> _
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
[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();
}
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:
System.ServiceModel.ICommunicationObject.Open auf dem Kanal, das durch einen Aufruf an System.ServiceModel.ChannelFactory.CreateChannel zurückgegeben wurde.
System.ServiceModel.ClientBase.Open für das WCF-Clientobjekt, das vom ServiceModel Metadata Utility-Tool (Svcutil.exe) generiert wurde.
Einen Initiierungsvorgang an einem Typ eines WCF-Clientobjekts (standardmäßig sind alle Vorgänge Initiierungsvorgänge). Wenn der erste Vorgang aufgerufen wird, öffnet das WCF-Clientobjekt den Kanal automatisch und initiiert eine Sitzung.
Ein Client beendet eine Sitzung in der Regel mit einem Dienstendpunkt, indem er einen der folgenden Vorgänge aufruft:
System.ServiceModel.ICommunicationObject.Close auf dem Kanal, das durch einen Aufruf an System.ServiceModel.ChannelFactory.CreateChannel zurückgegeben wurde.
System.ServiceModel.ClientBase.Close am WCF-Clientobjekt, das von Svcutil.exe generiert wurde.
Einen Beendigungsvorgang für einen Typ 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 Vorgehensweise: Erstellen eines Diensts, der Sitzungen erfordert sowie unter Standard-Dienstverhalten und Instanziierung.
Weitere Informationen über 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 System.ServiceModel.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. Ein vollständiges Beispiel finden Sie unter InstanceContextSharing.
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 PerSession festgelegt 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 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. |