Korzystanie z sesji

W aplikacjach programu Windows Communication Foundation (WCF) sesja koreluje grupę komunikatów z konwersacją. Sesje programu WCF różnią się od obiektu sesji dostępnego w aplikacjach ASP.NET, obsługują różne zachowania i są kontrolowane na różne sposoby. W tym temacie opisano funkcje, które sesje są włączone w aplikacjach WCF i jak ich używać.

Sesje w aplikacjach Windows Communication Foundation

Gdy kontrakt usługi określa, że wymaga sesji, umowa określa, że wszystkie wywołania (czyli podstawowe wymiany komunikatów, które obsługują połączenia) muszą być częścią tej samej konwersacji. Jeśli kontrakt określa, że zezwala na sesje, ale nie wymaga tego, klienci mogą nawiązać połączenie i ustanowić sesję lub nie ustanowić sesji. Jeśli sesja zakończy się, a komunikat jest wysyłany za pośrednictwem tego samego kanału, zgłaszany jest wyjątek.

Sesje programu WCF mają następujące główne funkcje koncepcyjne:

  • Są one jawnie inicjowane i przerywane przez aplikację wywołującą (klienta WCF).

  • Komunikaty dostarczane podczas sesji są przetwarzane w kolejności, w której są odbierane.

  • Sesje skorelują grupę wiadomości z konwersacją. Możliwe są różne typy korelacji. Na przykład jeden kanał oparty na sesji może korelować komunikaty na podstawie udostępnionego połączenia sieciowego, podczas gdy inny kanał oparty na sesji może skorelować komunikaty na podstawie tagu udostępnionego w treści komunikatu. Funkcje, które mogą pochodzić z sesji, zależą od charakteru korelacji.

  • Brak ogólnego magazynu danych skojarzonego z sesją programu WCF.

Jeśli znasz klasę System.Web.SessionState.HttpSessionState w aplikacjach ASP.NET i udostępnianą przez nią funkcjonalność, możesz zauważyć następujące różnice między sesjami tego rodzaju i sesjami WCF:

  • ASP.NET sesje są zawsze inicjowane przez serwer.

  • ASP.NET sesje są niejawnie nieurządkowane.

  • ASP.NET sesje zapewniają ogólny mechanizm przechowywania danych między żądaniami.

W tym temacie opisano:

  • Domyślne zachowanie wykonywania podczas korzystania z powiązań opartych na sesji w warstwie modelu usługi.

  • Typy funkcji udostępnianych przez powiązania oparte na sesji programu WCF.

  • Jak utworzyć kontrakt, który deklaruje wymaganie sesji.

  • Jak zrozumieć i kontrolować tworzenie i kończenie sesji oraz relację sesji z wystąpieniem usługi.

Domyślne zachowanie wykonywania przy użyciu sesji

Powiązanie, które próbuje zainicjować sesję, jest nazywane powiązaniem opartym na sesji. Kontrakty usług określają, że wymagają, zezwalają lub odrzucają powiązania oparte na sesji, ustawiając ServiceContractAttribute.SessionMode właściwość interfejsu kontraktu usługi (lub klasy) na jedną z System.ServiceModel.SessionMode wartości wyliczenia. Domyślnie wartość tej właściwości to Allowed, co oznacza, że jeśli klient używa powiązania opartego na sesji z implementacją usługi WCF, usługa ustanawia i używa podanej sesji.

Gdy usługa WCF akceptuje sesję klienta, następujące funkcje są domyślnie włączone:

  1. Wszystkie wywołania między obiektem klienta WCF są obsługiwane przez to samo wystąpienie usługi.

  2. Różne powiązania oparte na sesji zapewniają dodatkowe funkcje.

Typy sesji dostarczone przez system

Powiązanie oparte na sesji obsługuje domyślne skojarzenie wystąpienia usługi z określoną sesją. Jednak różne powiązania oparte na sesji obsługują różne funkcje oprócz włączenia wcześniej opisanej kontroli stancing opartej na sesji.

Program WCF udostępnia następujące typy zachowań aplikacji opartych na sesji:

SessionMode Ustawienie właściwości nie określa typu sesji, której wymaga kontrakt, tylko tego wymaga.

Tworzenie kontraktu wymagającego sesji

Utworzenie kontraktu wymagającego sesji stwierdza, że grupa operacji zadeklarowanych przez kontrakt usługi musi być wykonywana w ramach tej samej sesji i że komunikaty muszą być dostarczane w kolejności. Aby potwierdzić poziom obsługi sesji wymagany przez kontrakt usługi, ustaw ServiceContractAttribute.SessionMode właściwość interfejsu kontraktu usługi lub klasy na wartość System.ServiceModel.SessionMode wyliczenia, aby określić, czy kontrakt:

  • Wymaga sesji.

  • Umożliwia klientowi ustanowienie sesji.

  • Uniemożliwia sesję.

SessionMode Ustawienie właściwości nie określa jednak typu zachowania opartego na sesji wymaganego przez kontrakt. Powoduje to, że program WCF potwierdzi w czasie wykonywania, że skonfigurowane powiązanie (które tworzy kanał komunikacyjny) dla usługi, nie, nie lub może ustanowić sesję podczas implementowania usługi. Ponownie powiązanie może spełniać to wymaganie przy użyciu dowolnego typu wybranego zachowania opartego na sesji — zabezpieczeń, transportu, niezawodności lub niektórych kombinacji. Dokładne zachowanie zależy od wybranej System.ServiceModel.SessionMode wartości. Jeśli skonfigurowane powiązanie usługi nie jest zgodne z wartością SessionMode, zgłaszany jest wyjątek. Powiązania i kanały, które tworzą, że sesje pomocy technicznej są określane jako oparte na sesji.

Poniższy kontrakt usługi określa, że wszystkie operacje w obiekcie ICalculatorSession muszą być wymieniane w ramach sesji. Żadna z operacji nie zwraca wartości do obiektu wywołującego z wyjątkiem Equals metody . Equals Jednak metoda nie przyjmuje żadnych parametrów i dlatego może zwrócić tylko wartość niezerową wewnątrz sesji, w której dane zostały już przekazane do innych operacji. Ten kontrakt wymaga prawidłowego działania sesji. Bez sesji skojarzonej z określonym klientem wystąpienie usługi nie ma możliwości poznania poprzednich danych wysłanych przez tego klienta.

[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

Jeśli usługa zezwala na sesję, sesja jest ustanawiana i używana, jeśli klient inicjuje sesję; w przeciwnym razie nie zostanie ustanowiona żadna sesja.

Sesje i wystąpienia usług

Jeśli używasz domyślnego zachowania instancing w programie WCF, wszystkie wywołania między obiektem klienta WCF są obsługiwane przez to samo wystąpienie usługi. W związku z tym na poziomie aplikacji można traktować sesję jako włączenie zachowania aplikacji podobnego do zachowania wywołania lokalnego. Na przykład podczas tworzenia obiektu lokalnego:

  • Wywoływany jest konstruktor.

  • Wszystkie kolejne wywołania do odwołania do obiektu klienta programu WCF są przetwarzane przez to samo wystąpienie obiektu.

  • Destruktor jest wywoływany, gdy odwołanie do obiektu zostanie zniszczone.

Sesje umożliwiają podobne zachowanie między klientami i usługami, o ile jest używane domyślne zachowanie wystąpienia usługi. Jeśli kontrakt usługi wymaga sesji lub obsługuje je, co najmniej jedna operacja kontraktu może być oznaczona jako inicjowanie lub kończenie sesji przez ustawienie IsInitiating właściwości i IsTerminating .

Inicjowanie operacji to operacje , które muszą być wywoływane jako pierwsza operacja nowej sesji. Operacje inicjujące można wywołać tylko po wywołaniu co najmniej jednej operacji inicjującej. W związku z tym można utworzyć rodzaj konstruktora sesji dla usługi, deklarując inicjowanie operacji mających na celu pobieranie danych wejściowych od klientów odpowiednich do początku wystąpienia usługi. (Stan jest jednak skojarzony z sesją, a nie z obiektem usługi).

Operacje zakończenia to operacje, które muszą być wywoływane jako ostatni komunikat w istniejącej sesji. W domyślnym przypadku program WCF odzyskuje obiekt usługi i jego kontekst po sesji, z którą skojarzono usługę, jest zamykana. W związku z tym można utworzyć rodzaj destruktora, deklarując operacje zakończenia przeznaczone do wykonywania funkcji odpowiedniej na końcu wystąpienia usługi.

Uwaga

Mimo że domyślne zachowanie ma podobieństwo do lokalnych konstruktorów i destruktorów, jest to tylko podobieństwo. Każda operacja usługi WCF może być operacją inicjującą lub kończącą się albo obie w tym samym czasie. Ponadto w przypadku domyślnym operacje inicjowania mogą być wywoływane dowolną liczbę razy w dowolnej kolejności; po ustanowieniu sesji i skojarzeniu z wystąpieniem nie są tworzone żadne dodatkowe sesje, chyba że jawnie kontrolujesz okres istnienia wystąpienia usługi (przez manipulowanie obiektem System.ServiceModel.InstanceContext ). Na koniec stan jest skojarzony z sesją, a nie z obiektem usługi.

Na przykład ICalculatorSession kontrakt używany w poprzednim przykładzie wymaga, aby obiekt klienta WCF najpierw wywołał operację Clear przed inną operacją i że sesja z tym obiektem klienta WCF powinna zakończyć się po wywołaniu Equals operacji. Poniższy przykład kodu przedstawia kontrakt, który wymusza te wymagania. Clear musi być wywoływana jako pierwsza, aby zainicjować sesję, a sesja kończy się po Equals wywołaniu.

[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

Usługi nie uruchamiają sesji z klientami. W aplikacjach klienckich programu WCF istnieje bezpośrednia relacja między okresem istnienia kanału opartego na sesji a okresem istnienia samej sesji. W związku z tym klienci tworzą nowe sesje, tworząc nowe kanały oparte na sesji i usuwając istniejące sesje, zamykając bezpiecznie kanały oparte na sesji. Klient rozpoczyna sesję z punktem końcowym usługi, wywołując jedną z następujących czynności:

Zazwyczaj klient kończy sesję z punktem końcowym usługi, wywołując jedną z następujących czynności:

  • ICommunicationObject.Close w kanale zwróconym przez wywołanie metody ChannelFactory<TChannel>.CreateChannel.

  • ClientBase<TChannel>.Close na obiekcie klienta programu WCF wygenerowany przez Svcutil.exe.

  • Operacja zakończenia dla dowolnego typu obiektu klienta WCF (domyślnie żadne operacje nie kończą się; kontrakt musi jawnie określić operację zakończenia). Po wywołaniu pierwszej operacji obiekt klienta programu WCF automatycznie otwiera kanał i inicjuje sesję.

Przykłady można znaleźć w temacie How to: Create a Service That Requires Sessions (Jak utworzyć usługę, która wymaga sesji ), a także przykłady domyślnego zachowania usługi i instancingu .

Aby uzyskać więcej informacji na temat klientów i sesji, zobacz Uzyskiwanie dostępu do usług przy użyciu klienta WCF.

Interakcje sesji z Ustawienia InstanceContext

Istnieje interakcja między SessionMode wyliczeniem w kontrakcie a ServiceBehaviorAttribute.InstanceContextMode właściwością, która kontroluje skojarzenie między kanałami a określonymi obiektami usługi. Aby uzyskać więcej informacji, zobacz Sesje, Instancing i Współbieżność.

Udostępnianie obiektów InstanceContext

Możesz również kontrolować, który kanał lub wywołanie oparte na sesji jest skojarzone z tym InstanceContext obiektem, wykonując to skojarzenie samodzielnie.

Sesje i przesyłanie strumieniowe

Jeśli masz dużą ilość danych do transferu, tryb przesyłania strumieniowego w programie WCF jest wykonalną alternatywą dla domyślnego zachowania buforowania i przetwarzania komunikatów w pamięci w całości. Podczas przesyłania strumieniowego wywołań z powiązaniem opartym na sesji może wystąpić nieoczekiwane zachowanie. Wszystkie wywołania przesyłania strumieniowego są wykonywane za pośrednictwem jednego kanału (kanału datagramu), który nie obsługuje sesji, nawet jeśli używane powiązanie jest skonfigurowane do używania sesji. Jeśli wielu klientów wykonuje wywołania przesyłania strumieniowego do tego samego obiektu usługi za pośrednictwem powiązania opartego na sesji, a tryb współbieżności obiektu usługi jest ustawiony na pojedynczy, a jego tryb kontekstu wystąpienia jest ustawiony na PerSessionwartość , wszystkie wywołania muszą przechodzić przez kanał datagramu i dlatego tylko jedno wywołanie jest przetwarzane w danym momencie. Jeden lub więcej klientów może wtedy upłynął limit czasu. Ten problem można obejść, ustawiając wartość obiektu InstanceContextMode usługi na PerCall wartość lub współbieżność na wiele.

Uwaga

MaxConcurrentSessions nie mają wpływu w tym przypadku, ponieważ jest dostępna tylko jedna "sesja".

Zobacz też