Použití relací

V aplikacích WCF (Windows Communication Foundation) relace koreluje skupinu zpráv do konverzace. Relace WCF se liší od objektu relace dostupného v ASP.NET aplikacích, podporují různá chování a řídí se různými způsoby. Toto téma popisuje funkce, které relace umožňují v aplikacích WCF a jak je používat.

Relace v aplikacích Windows Communication Foundation

Když kontrakt služby určuje, že vyžaduje relaci, musí být součástí stejné konverzace všechna volání (tj. podkladová výměna zpráv podporující volání). Pokud kontrakt určuje, že umožňuje relace, ale nevyžaduje ho, klienti se mohou připojit a buď vytvořit relaci, nebo nenavázat relaci. Pokud relace skončí a zpráva se odešle přes stejný kanál, vyvolá se výjimka.

Relace WCF mají následující hlavní koncepční funkce:

  • Jsou explicitně inicializovány a ukončeny volající aplikací (klient WCF).

  • Zprávy doručované během relace se zpracovávají v pořadí, ve kterém se přijímají.

  • Relace korelují skupinu zpráv do konverzace. Různé typy korelace jsou možné. Jeden kanál založený na relaci může například korelovat zprávy založené na sdíleném síťovém připojení, zatímco jiný kanál založený na relaci může korelovat zprávy na základě sdílené značky v textu zprávy. Funkce, které lze odvodit z relace, závisí na povaze korelace.

  • K relaci WCF není přidružené žádné obecné úložiště dat.

Pokud znáte System.Web.SessionState.HttpSessionState třídu v ASP.NET aplikacích a funkcích, které poskytuje, můžete si všimnout následujících rozdílů mezi tímto druhem relací a relacemi WCF:

  • ASP.NET relace jsou vždy zahájeny serverem.

  • ASP.NET relace jsou implicitně neuspořádané.

  • ASP.NET relace poskytují obecný mechanismus úložiště dat napříč požadavky.

Toto téma popisuje:

  • Výchozí chování při provádění při použití vazeb založených na relacích ve vrstvě modelu služby.

  • Typy funkcí, které poskytují vazby poskytované systémem založené na relacích WCF.

  • Jak vytvořit kontrakt, který deklaruje požadavek relace.

  • Jak pochopit a řídit vytváření a ukončení relace a vztah relace k instanci služby.

Výchozí chování při spouštění pomocí relací

Vazba, která se pokusí zahájit relaci, se nazývá vazba založená na relaci. Kontrakty služeb určují, že vyžadují, povolují nebo odmítnou vazby založené na relacích nastavením ServiceContractAttribute.SessionMode vlastnosti rozhraní kontraktu služby (nebo třídy) na jednu z hodnot výčtu System.ServiceModel.SessionMode . Ve výchozím nastavení je Allowedhodnota této vlastnosti , což znamená, že pokud klient používá vazbu založenou na relaci s implementací služby WCF, služba vytvoří a použije poskytnutou relaci.

Když služba WCF přijme relaci klienta, ve výchozím nastavení jsou povoleny následující funkce:

  1. Všechna volání mezi objektem klienta WCF se zpracovávají stejnou instancí služby.

  2. Různé vazby založené na relacích poskytují další funkce.

Typy relací poskytované systémem

Vazba založená na relaci podporuje výchozí přidružení instance služby k určité relaci. Různé vazby založené na relacích ale podporují různé funkce kromě povolení řízení vytváření instancí na základě relace, které jsme popsali dříve.

WCF poskytuje následující typy chování aplikace založené na relacích:

SessionMode Nastavení vlastnosti neurčí typ relace, kterou kontrakt vyžaduje, pouze to, že vyžaduje jednu.

Vytvoření kontraktu, který vyžaduje relaci

Vytvoření kontraktu, který vyžaduje relaci, uvádí, že skupina operací, které kontrakt služby deklaruje, musí být spuštěna ve stejné relaci a že zprávy musí být doručeny v pořadí. Pokud chcete uplatnit úroveň podpory relace, kterou vyžaduje kontrakt služby, nastavte ServiceContractAttribute.SessionMode vlastnost rozhraní kontraktu služby nebo třídu na hodnotu výčtu System.ServiceModel.SessionMode , abyste určili, zda kontrakt:

  • Vyžaduje relaci.

  • Umožňuje klientovi vytvořit relaci.

  • Zakáže relaci.

SessionMode Nastavení vlastnosti však neurčí typ chování na základě relace, které kontrakt vyžaduje. Dává WCF pokyn k potvrzení v době běhu, že nakonfigurovaná vazba (která vytvoří komunikační kanál) pro službu, ne nebo může vytvořit relaci při implementaci služby. Vazba opět může splňovat tento požadavek s jakýmkoli typem chování založeného na relacích, které zvolí – zabezpečení, přenos, spolehlivá nebo nějaká kombinace. Přesné chování závisí na vybrané hodnotě System.ServiceModel.SessionMode . Pokud nakonfigurovaná vazba služby neodpovídá hodnotě SessionMode, vyvolá se výjimka. Vazby a kanály, které vytvářejí, které podporují relace, se říká, že jsou založené na relacích.

Následující kontrakt služby určuje, že všechny operace v ICalculatorSession relaci musí být vyměněné. Žádná z operací nevrací hodnotu volajícímu s výjimkou Equals metody. Equals Metoda však nepřijímá žádné parametry, a proto může vrátit pouze nenulovou hodnotu uvnitř relace, ve které již byla data předána ostatním operacím. Tento kontrakt vyžaduje, aby relace fungovala správně. Bez relace přidružené ke konkrétnímu klientovi nemá instance služby žádný způsob, jak zjistit, jaká předchozí data klient odeslal.

[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

Pokud služba umožňuje relaci, vytvoří se relace a použije se, pokud ji klient inicializuje; v opačném případě není vytvořena žádná relace.

Relace a instance služeb

Pokud ve WCF použijete výchozí chování vytváření instancí, budou všechna volání mezi klientským objektem WCF zpracována stejnou instancí služby. Na úrovni aplikace si proto můžete představit relaci jako povolení chování aplikace podobné chování místního volání. Například při vytváření místního objektu:

  • Volá se konstruktor.

  • Všechna následná volání odkazu na objekt klienta WCF jsou zpracována stejnou instancí objektu.

  • Destruktor je volána při zničení odkazu na objekt.

Relace umožňují podobné chování mezi klienty a službami, pokud se použije výchozí chování instance služby. Pokud kontrakt služby vyžaduje nebo podporuje relace, je možné jednu nebo více operací kontraktu označit jako iniciační nebo ukončující relaci nastavením IsInitiating a IsTerminating vlastnostmi.

Iniciační operace jsou ty, které musí být volána jako první operace nové relace. Neicializovány operace lze volat pouze po zavolání aspoň jedné iniciační operace. Proto můžete vytvořit druh konstruktoru relace pro vaši službu deklarováním inicializování operací navržených tak, aby vstupy od klientů odpovídajících začátku instance služby. (Stav je však přidružený k relaci, a ne objekt služby.)

Ukončovací operace jsou naopak ty, které musí být volána jako poslední zpráva v existující relaci. Ve výchozím případě WCF recykluje objekt služby a jeho kontext po relaci, ke které byla služba přidružena, je uzavřena. Můžete tedy vytvořit druh destruktoru deklarováním ukončovacích operací navržených tak, aby prováděly funkci odpovídající konci instance služby.

Poznámka:

I když výchozí chování nese podobnost s místními konstruktory a destruktory, je to jen podobnost. Libovolnou operací služby WCF může být iniciační nebo ukončovací operace nebo obojí současně. Kromě toho ve výchozím případě lze iniciační operace volat libovolný početkrát v libovolném pořadí; Po vytvoření relace a přidružení k instanci nejsou vytvořeny žádné další relace, pokud explicitně neřídíte životnost instance služby (manipulací s objektem System.ServiceModel.InstanceContext ). Nakonec je stav přidružený k relaci, nikoli k objektu služby.

Například kontrakt použitý v předchozím příkladu vyžaduje, ICalculatorSession aby klientský objekt WCF nejprve volal Clear operaci před jakoukoli jinou operací a že relace s tímto objektem klienta WCF by se měla ukončit při volání Equals operace. Následující příklad kódu ukazuje kontrakt, který vynucuje tyto požadavky. Clear musí být volána jako první, aby se spustila relace a tato relace končí, když Equals je volána.

[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

Služby nespouštějí relace s klienty. V klientských aplikacích WCF existuje přímý vztah mezi životností kanálu založeného na relaci a životností samotné relace. Klienti proto vytvářejí nové relace tím, že vytvářejí nové kanály založené na relacích a ruší stávající relace tím, že kanály založené na relacích řádně ukončí. Klient spustí relaci s koncovým bodem služby voláním jedné z následujících možností:

Klient obvykle ukončí relaci koncovým bodem služby voláním jedné z následujících možností:

  • ICommunicationObject.Close na kanálu vráceného voláním ChannelFactory<TChannel>.CreateChannel.

  • ClientBase<TChannel>.Close objekt klienta WCF vygenerovaný Svcutil.exe.

  • Ukončovací operace u některého typu klientského objektu WCF (ve výchozím nastavení nejsou ukončovány žádné operace; kontrakt musí explicitně zadat ukončovací operaci). Při volání první operace klientský objekt WCF automaticky otevře kanál a zahájí relaci.

Příklady najdete v tématu Postupy: Vytvoření služby, která vyžaduje relace , a také výchozí chování služby a ukázky vytváření instancí .

Další informace o klientech a relacích naleznete v tématu Přístup ke službám pomocí klienta WCF.

Relace interagují s Nastavení InstanceContext

Mezi výčtem SessionMode v kontraktu ServiceBehaviorAttribute.InstanceContextMode a vlastností existuje interakce, která řídí přidružení mezi kanály a konkrétními objekty služby. Další informace najdete v tématu Relace, Vytváření instancí a Souběžnost.

Sdílení objektů InstanceContext

Můžete také určit, který kanál nebo volání relace je přidružen k jakému InstanceContext objektu, provedením přidružení sami.

Relace a streamování

Pokud máte velké množství dat k přenosu, je režim přenosu streamování ve WCF vhodná alternativa k výchozímu chování ukládání do vyrovnávací paměti a zpracování zpráv v celé paměti. Při streamování volání pomocí vazby založené na relaci se může zobrazit neočekávané chování. Všechna streamovaná volání se provádějí prostřednictvím jednoho kanálu (kanálu datagramu), který nepodporuje relace, i když je použitá vazba nakonfigurovaná tak, aby používala relace. Pokud více klientů provádí streamování volání stejného objektu služby přes vazbu založenou na relaci a režim souběžnosti objektu služby je nastavený na jeden a jeho kontextový režim instance je nastaven na PerSession, všechna volání musí projít kanálem datagramu, takže se zpracuje vždy jen jedno volání. Jeden nebo více klientů pak může vypršel časový limit. Tento problém můžete vyřešit nastavením objektu InstanceContextMode služby na PerCall více objektů služby nebo souběžností na více.

Poznámka:

MaxConcurrentSessions v tomto případě nemají žádný vliv, protože je k dispozici pouze jedna relace.

Viz také