Använda sessioner
I WCF-program (Windows Communication Foundation) korrelerar en session en grupp meddelanden i en konversation. WCF-sessioner skiljer sig från sessionsobjektet som är tillgängligt i ASP.NET program, stöder olika beteenden och styrs på olika sätt. Det här avsnittet beskriver de funktioner som sessioner aktiverar i WCF-program och hur du använder dem.
Sessioner i Windows Communication Foundation-program
När ett tjänstkontrakt anger att det kräver en session, anger det kontraktet att alla anrop (dvs. de underliggande meddelandeutbytena som stöder anropen) måste ingå i samma konversation. Om ett kontrakt anger att det tillåter sessioner men inte kräver en, kan klienter ansluta och antingen upprätta en session eller inte upprätta en session. Om sessionen avslutas och ett meddelande skickas via samma kanal utlöses ett undantag.
WCF-sessioner har följande huvudsakliga konceptuella funktioner:
De initieras och avslutas uttryckligen av det anropande programmet (WCF-klienten).
Meddelanden som levereras under en session bearbetas i den ordning de tas emot.
Sessioner korrelerar en grupp meddelanden i en konversation. Olika typer av korrelation är möjliga. Till exempel kan en sessionsbaserad kanal korrelera meddelanden baserat på en delad nätverksanslutning, medan en annan sessionsbaserad kanal kan korrelera meddelanden baserat på en delad tagg i meddelandetexten. Vilka funktioner som kan härledas från sessionen beror på korrelationens natur.
Det finns inget allmänt datalager som är associerat med en WCF-session.
Om du är bekant med System.Web.SessionState.HttpSessionState klassen i ASP.NET program och de funktioner som den tillhandahåller kan du märka följande skillnader mellan den typen av sessioner och WCF-sessioner:
ASP.NET sessioner är alltid serverinitierade.
ASP.NET sessioner är implicit oordnade.
ASP.NET sessioner tillhandahåller en allmän mekanism för datalagring mellan begäranden.
I det här avsnittet beskrivs:
Standardkörningsbeteendet när du använder sessionsbaserade bindningar i tjänstmodelllagret.
De typer av funktioner som WCF-sessionsbaserade, systembaserade bindningar tillhandahåller.
Så här skapar du ett kontrakt som deklarerar ett sessionskrav.
Så här förstår och kontrollerar du skapande och avslutning av sessionen och relationen mellan sessionen och tjänstinstansen.
Standardkörningsbeteende med sessioner
En bindning som försöker initiera en session kallas för en sessionsbaserad bindning. Tjänstkontrakt anger att de kräver, tillåter eller nekar sessionsbaserade bindningar genom att ställa in ServiceContractAttribute.SessionMode egenskapen på servicekontraktets gränssnitt (eller klass) till något av System.ServiceModel.SessionMode uppräkningsvärdena. Som standard är Allowedvärdet för den här egenskapen , vilket innebär att om en klient använder en sessionsbaserad bindning med en WCF-tjänstimplementering upprättar och använder tjänsten den angivna sessionen.
När en WCF-tjänst accepterar en klientsession aktiveras följande funktioner som standard:
Alla anrop mellan ett WCF-klientobjekt hanteras av samma tjänstinstans.
Olika sessionsbaserade bindningar ger ytterligare funktioner.
Systemspecifika sessionstyper
En sessionsbaserad bindning stöder standardassociationen för en tjänstinstans med en viss session. Olika sessionsbaserade bindningar stöder dock olika funktioner förutom att aktivera den sessionsbaserade instancing-kontrollen som beskrivits tidigare.
WCF tillhandahåller följande typer av sessionsbaserat programbeteende:
Stöder System.ServiceModel.Channels.SecurityBindingElement säkerhetsbaserade sessioner, där båda kommunikationssluten har kommit överens om en specifik säker konversation. Mer information finns i Skydda tjänster. Till exempel använder bindningen System.ServiceModel.WSHttpBinding , som innehåller stöd för både säkerhetssessioner och tillförlitliga sessioner, som standard endast en säker session som krypterar och signerar meddelanden digitalt.
Bindningen System.ServiceModel.NetTcpBinding stöder TCP/IP-baserade sessioner för att säkerställa att alla meddelanden korreleras av anslutningen på socketnivå.
Elementet System.ServiceModel.Channels.ReliableSessionBindingElement , som implementerar WS-ReliableMessaging-specifikationen, ger stöd för tillförlitliga sessioner där meddelanden kan konfigureras att levereras i ordning och exakt en gång, vilket säkerställer att meddelanden tas emot även när meddelanden färdas över flera noder under konversationen. Mer information finns i Tillförlitliga sessioner.
Bindningen System.ServiceModel.NetMsmqBinding tillhandahåller MSMQ-datagramsessioner. Mer information finns i Köer i WCF.
SessionMode Att ange egenskapen anger inte vilken typ av session kontraktet kräver, bara att det kräver en.
Skapa ett kontrakt som kräver en session
När du skapar ett kontrakt som kräver en session anges att den grupp av åtgärder som tjänstkontraktet deklarerar måste köras inom samma session och att meddelanden måste levereras i ordning. Om du vill kontrollera nivån på sessionssupporten som ett tjänstkontrakt kräver anger du ServiceContractAttribute.SessionMode egenskapen i ditt tjänstkontraktsgränssnitt eller -klass till värdet för System.ServiceModel.SessionMode uppräkningen för att ange om kontraktet:
Kräver en session.
Tillåter att en klient upprättar en session.
Förbjuder en session.
SessionMode Att ange egenskapen anger dock inte vilken typ av sessionsbaserat beteende kontraktet kräver. Den instruerar WCF att vid körning bekräfta att den konfigurerade bindningen (som skapar kommunikationskanalen) för tjänsten inte gör, inte eller kan upprätta en session när en tjänst implementeras. Bindningen kan återigen uppfylla det kravet med alla typer av sessionsbaserat beteende som den väljer – säkerhet, transport, tillförlitlig eller någon kombination. Det exakta beteendet beror på det System.ServiceModel.SessionMode valda värdet. Om den konfigurerade bindningen för tjänsten inte överensstämmer med värdet SessionModeför genereras ett undantag. Bindningar och de kanaler som de skapar som stödsessioner sägs vara sessionsbaserade.
Följande tjänstkontrakt anger att alla åtgärder i ICalculatorSession
måste bytas ut inom en session. Ingen av åtgärderna returnerar ett värde till anroparen förutom Equals
metoden. Metoden tar dock Equals
inga parametrar och kan därför bara returnera ett värde som inte är noll i en session där data redan har skickats till de andra åtgärderna. Det här kontraktet kräver en session för att fungera korrekt. Utan en session som är associerad med en specifik klient har tjänstinstansen inget sätt att veta vilka tidigare data som klienten har skickat.
[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
Om en tjänst tillåter en session upprättas och används en session om klienten initierar en. annars upprättas ingen session.
Sessioner och tjänstinstanser
Om du använder standardbeteendet för instancing i WCF hanteras alla anrop mellan ett WCF-klientobjekt av samma tjänstinstans. På programnivå kan du därför betrakta en session som att aktivera programbeteende som liknar det lokala anropsbeteendet. När du till exempel skapar ett lokalt objekt:
En konstruktor anropas.
Alla efterföljande anrop som görs till WCF-klientobjektreferensen bearbetas av samma objektinstans.
En destructor anropas när objektreferensen förstörs.
Sessioner möjliggör ett liknande beteende mellan klienter och tjänster så länge som standardbeteendet för tjänstinstansen används. Om ett tjänstkontrakt kräver eller stöder sessioner kan en eller flera kontraktsåtgärder markeras som att initiera eller avsluta en session genom att ange IsInitiating egenskaperna och IsTerminating .
Initierande åtgärder är de som måste anropas som den första åtgärden i en ny session. Icke-initierande åtgärder kan anropas endast efter att minst en initierande åtgärd har anropats. Du kan därför skapa en typ av sessionskonstruktor för din tjänst genom att deklarera initiera åtgärder som är utformade för att ta indata från klienter som är lämpliga för början av tjänstinstansen. (Tillståndet är dock associerat med sessionen och inte tjänstobjektet.)
Avslutande åtgärder är däremot de som måste anropas som det sista meddelandet i en befintlig session. I standardfallet återanvänder WCF tjänstobjektet och dess kontext efter att sessionen som tjänsten var associerad med har stängts. Du kan därför skapa en typ av destructor genom att deklarera avslutande åtgärder som är utformade för att utföra en funktion som är lämplig för slutet av tjänstinstansen.
Kommentar
Även om standardbeteendet har en likhet med lokala konstruktorer och destruktorer, är det bara en likhet. Alla WCF-tjänståtgärder kan vara en initierande eller avslutande åtgärd, eller båda samtidigt. I standardfallet kan dessutom initierande åtgärder anropas valfritt antal gånger i valfri ordning. inga ytterligare sessioner skapas när sessionen har upprättats och associerats med en instans om du inte uttryckligen kontrollerar livslängden för tjänstinstansen (genom att System.ServiceModel.InstanceContext manipulera objektet). Slutligen är tillståndet associerat med sessionen och inte tjänstobjektet.
Till exempel kräver kontraktet ICalculatorSession
som användes i föregående exempel att WCF-klientobjektet först anropar Clear
åtgärden före någon annan åtgärd och att sessionen med det här WCF-klientobjektet ska avslutas när åtgärden anropas Equals
. I följande kodexempel visas ett kontrakt som tillämpar dessa krav. Clear
måste anropas först för att initiera en session, och den sessionen avslutas när Equals
anropas.
[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
Tjänster startar inte sessioner med klienter. I WCF-klientprogram finns det en direkt relation mellan den sessionsbaserade kanalens livslängd och själva sessionens livslängd. Därför skapar klienter nya sessioner genom att skapa nya sessionsbaserade kanaler och riva ned befintliga sessioner genom att stänga sessionsbaserade kanaler på ett smidigt sätt. En klient startar en session med en tjänstslutpunkt genom att anropa något av följande:
ICommunicationObject.Open på kanalen som returneras av ett anrop till ChannelFactory<TChannel>.CreateChannel.
ClientBase<TChannel>.Open på WCF-klientobjektet som genereras av ServiceModel Metadata Utility Tool (Svcutil.exe).
En initierande åtgärd för någon av typerna av WCF-klientobjekt (som standard initieras alla åtgärder). När den första åtgärden anropas öppnar WCF-klientobjektet automatiskt kanalen och initierar en session.
Vanligtvis avslutar en klient en session med en tjänstslutpunkt genom att anropa något av följande:
ICommunicationObject.Close på kanalen som returneras av ett anrop till ChannelFactory<TChannel>.CreateChannel.
ClientBase<TChannel>.Close på WCF-klientobjektet som genereras av Svcutil.exe.
En avslutande åtgärd för någon av typerna av WCF-klientobjekt (som standard avslutas inga åtgärder. Kontraktet måste uttryckligen ange en avslutande åtgärd). När den första åtgärden anropas öppnar WCF-klientobjektet automatiskt kanalen och initierar en session.
Exempel finns i How to: Create a Service That Requires Sessions as as the Default Service Behavior and Instancing samples (Så här skapar du en tjänst som kräver sessioner samt standardtjänstbeteende och instancing-exempel).
Mer information om klienter och sessioner finns i Åtkomst till tjänster med hjälp av en WCF-klient.
Sessioner interagerar med InstanceContext Inställningar
Det finns en interaktion mellan SessionMode uppräkningen i ett kontrakt och ServiceBehaviorAttribute.InstanceContextMode egenskapen som styr associationen mellan kanaler och specifika tjänstobjekt. Mer information finns i Sessioner, Instancing och Concurrency.
Dela InstanceContext-objekt
Du kan också styra vilken sessionsbaserad kanal eller vilket anrop som är associerat med vilket InstanceContext objekt genom att utföra associationen själv.
Sessioner och direktuppspelning
När du har en stor mängd data att överföra är strömningsöverföringsläget i WCF ett möjligt alternativ till standardbeteendet för buffring och bearbetning av meddelanden i minnet i sin helhet. Du kan få ett oväntat beteende när du strömmar anrop med en sessionsbaserad bindning. Alla strömningsanrop görs via en enda kanal (datagramkanalen) som inte stöder sessioner även om bindningen som används är konfigurerad för att använda sessioner. Om flera klienter gör strömningsanrop till samma tjänstobjekt via en sessionsbaserad bindning och tjänstobjektets samtidighetsläge är inställt på enkel och dess instanskontextläge är inställt PerSession
på , måste alla anrop gå via datagramkanalen och därför bearbetas bara ett anrop i taget. En eller flera klienter kan sedan överskrida tidsgränsen. Du kan kringgå det här problemet genom att antingen ange tjänstobjektets InstanceContextMode
till PerCall
eller Samtidighet till flera.
Kommentar
MaxConcurrentSessions har ingen effekt i det här fallet eftersom det bara finns en "session" tillgänglig.