Volba vzoru výměny zpráv

Prvním krokem při vytváření vlastního způsobu přenosu je rozhodnout, které vzory výměny zpráv (nebo MEPs) jsou požadované pro kanál, který vyvíjíte. Toto téma popisuje dostupné možnosti a popisuje různé požadavky. Toto je první úloha v seznamu úkolů vývoje kanálu popsaném v části Vývoj kanálů.

Šest vzorů výměny zpráv

Existují tři poslanci, kteří si můžou vybrat:

  • Datagram (IInputChannel a IOutputChannel)

    Při použití MEP datagramu odešle klient zprávu ve stylu 'vystřel a zapomeň' výměnu. Systém odeslání bez zpětné vazby je ten, který vyžaduje potvrzení úspěšného doručení mimo hlavní tok. Zpráva může být ztracena při přenosu a nikdy se nedostanou ke službě. Pokud se operace odeslání úspěšně dokončí na straně klienta, nezaručuje, že vzdálený koncový bod obdržel zprávu. Datagram je základním stavebním blokem pro zasílání zpráv, protože nad ním můžete vytvářet vlastní protokoly– včetně spolehlivých protokolů a zabezpečených protokolů. Klientské kanály datagramu implementují rozhraní IOutputChannel, a služební kanály datagramu implementují rozhraní IInputChannel.

  • Request-Response (IRequestChannel a IReplyChannel)

    V tomto MEP se odešle zpráva a přijme se odpověď. Vzor se skládá z párů požadavků a odpovědí. Příklady volání typu požadavek-odezva zahrnují vzdálená volání procedur (RPC) a GET požadavky prohlížeče. Tento model se také označuje jako poloduplex. V tomto MEP implementují klientské kanály IRequestChannel a kanály služeb IReplyChannel.

  • Duplex (IDuplexChannel)

    Duplexní mep umožňuje, aby klient odeslal libovolný počet zpráv a přijal je v libovolném pořadí. Duplexní MEP je jako telefonní konverzace, kde každé slovo, které je řečeno, je zpráva. Vzhledem k tomu, že obě strany mohou odesílat a přijímat v tomto MEP, rozhraní implementované klientskými a servisními kanály je IDuplexChannel.

Vývojový diagram znázorňující tři základní vzory výměny zpráv Tři základní vzory výměny zpráv. Odshora dolů: datagram, požadavek-odpověď, a duplex.

Každý z těchto poslanců může také podporovat zasedání. Relace (a implementace System.ServiceModel.Channels.ISessionChannel<TSession> typu System.ServiceModel.Channels.ISession) spojuje všechny zprávy odeslané a přijaté na kanálu. Vzor odpovědi na požadavek je samostatná relace se dvěma zprávami, protože požadavek a odpověď korelují. Naproti tomu vzor žádost-odpověď, který podporuje relace, znamená, že všechny páry žádostí a odpovědí na daném kanálu jsou vzájemně korelovány. Získáte tak celkem šest poslanců, ze které si můžete vybrat:

  • Datagram

  • Požadavek-odpověď

  • Duplexní

  • Datagram s relacemi

  • Odpověď na žádost s relacemi

  • Duplexní režim s relacemi

Poznámka:

Pro přenos UDP je jediným podporovaným protokolem MEP datagram, protože UDP je ze své podstaty fire and forget protocol.

Relace a kanály s relacími

V síťovém světě existují protokoly orientované na připojení (například TCP) a protokoly bez připojení (například UDP). WCF používá termín "relace" pro označení logické abstrakce podobné připojení. Protokoly WCF s relacemi jsou podobné síťovým protokolům orientovaným na připojení a protokoly WCF bez relací se zase podobají síťovým protokolům bez připojení.

V modelu objektů kanálu se každá logická relace manifestuje jako instance stavového kanálu. Proto každá nová relace vytvořená klientem a přijatá ve službě odpovídá novému kanálu relace na každé straně. Následující diagram znázorňuje strukturu kanálů bez relací a v dolní části struktury kanálů s relacemi.

Diagram zobrazující strukturu kanálů bez relací a kanálů s relacemi

Klient vytvoří nový kanál relace a odešle zprávu. Na straně služby obdrží posluchač kanálu tuto zprávu a zjistí, že patří do nové relace, takže vytvoří nový kanál s relací a předá ho aplikaci (v reakci na volání aplikace na posluchač kanálu AcceptChannel). Aplikace pak obdrží tuto zprávu a všechny následné zprávy odeslané ve stejné relaci prostřednictvím stejného kanálu relace.

Jiný klient (nebo stejný klient) vytvoří novou relaci a odešle zprávu. Naslouchací proces kanálu zjistí, že tato zpráva je v nové relaci a vytvoří nový kanál relace a proces se opakuje.

Bez relací neexistuje žádná korelace mezi kanály a relacemi. Posluchač kanálu proto vytvoří pouze jeden kanál, kterým se doručují do aplikace všechny přijaté zprávy. Není k dispozici ani řazení zpráv, protože neexistuje žádná relace, ve které se má udržovat pořadí zpráv. Horní část předchozí grafiky znázorňuje výměnu zpráv bez použití relací.

Spouštění a ukončování relací

Spuštění relací na klientovi se provádí jednoduše vytvořením nového kanálu relace. Jsou zahájeny na službě, když služba obdrží zprávu poslanou v nové relaci. Podobně se relace ukončí zavřením nebo přerušením kanálu s relací.

Výjimkou je IDuplexSessionChannel to, co se používá pro odesílání i příjem zpráv v duplexním modelu komunikace v relaci. Je možné, že jedna strana bude chtít ukončit odesílání zpráv, ale dál přijímat zprávy, takže pokud používáte IDuplexSessionChannel mechanismus, který umožňuje zavřít výstupní relaci, která znamená, že nebudete odesílat žádné další zprávy, ale ponechat vstupní relaci otevřenou, což vám umožní pokračovat v přijímání zpráv.

Obecně platí, že relace se uzavírají na odchozí straně, nikoli na příchozí straně. To znamená, že výstupní kanály relace se dají zavřít, čímž se relace čistě ukončí. Zavření výstupního kanálu relace způsobí, že odpovídající vstupní kanál relace vrátí hodnotu null aplikaci volajícímu IInputChannel.Receive na rozhraní IDuplexSessionChannel.

Vstupní kanály relace by však neměly být uzavřeny, pokud IInputChannel.Receive při IDuplexSessionChannel vrátí hodnotu null, což znamená, že relace je již uzavřena. Pokud hodnota null u IInputChannel.Receive na IDuplexSessionChannel nebyla vrácena, může ukončení vstupního kanálu relace vyvolat výjimku, protože při zavírání může přijímat neočekávané zprávy. Pokud příjemce chce ukončit relaci předtím, než odesílatel provede, měl by zavolat Abort na vstupní kanál, který náhle ukončí relaci.

Tvorba stavových kanálů

Jako autor kanálu s relací existuje několik věcí, které váš kanál musí udělat, aby poskytoval relace. Na straně odesílání musí váš kanál:

  • Pro každý nový kanál vytvořte novou relaci a přidružte ji k novému ID relace, což je jedinečný řetězec. Nebo získejte novou relaci z kanálu s relacemi, který je pod vámi ve vrstvě.

  • Pro každou zprávu odeslanou pomocí tohoto kanálu, pokud váš kanál vytvořil relaci (na rozdíl od získání z níže uvedené vrstvy), musíte zprávu přidružit k relaci. U kanálů protokolu se to obvykle provádí přidáním hlavičky SOAP. V případě přenosových kanálů se to obvykle provádí vytvořením nového přenosového připojení nebo přidáním informací o relaci do framingového protokolu.

  • Pro každou zprávu poslanou pomocí tohoto kanálu musíte poskytnout záruky doručení uvedené výše. Pokud se spoléháte na kanál pod vaší úrovní, aby poskytl relaci, tento kanál vám také poskytne záruky doručení. Pokud relaci poskytujete sami, musíte tyto záruky implementovat jako součást vašeho protokolu. Obecně platí, že pokud píšete komunikační kanál, který předpokládá WCF na obou stranách, může být vyžadován přenos TCP nebo kanál spolehlivého zasílání zpráv a můžete se spolehnout na jeden z nich, aby poskytl relaci.

  • Když je ICommunicationObject.Close zavolán na vašem kanálu, proveďte potřebnou práci k zavření relace buď pomocí zadaného časového limitu, nebo výchozího časového limitu. To může být stejně jednoduché jako volání Close na kanál pod vámi (pokud jste právě z něj získali relaci) nebo odeslání speciální zprávy SOAP nebo zavření přenosového připojení.

  • Když je Abort volána na vašem kanálu, okamžitě ukončete relaci bez provádění vstupně-výstupních operací (I/O). To může znamenat, že nic neděláte nebo může zahrnovat přerušení síťového připojení nebo jiného prostředku.

Na straně příjmu váš kanál musí:

  • Pro každou příchozí zprávu musí posluchač kanálu zjistit relaci, do které patří. Pokud se jedná o první zprávu v relaci, posluchač kanálu musí vytvořit nový kanál a vrátit ho při volání na IChannelListener<TChannel>.AcceptChannel. V opačném případě musí posluchač kanálu najít existující kanál, který odpovídá relaci, a doručit zprávu tímto kanálem.

  • Pokud váš komunikační kanál poskytuje relaci (spolu s požadovanými zárukami doručení), na přijímací straně může být potřeba provést některé kroky, jako je znovu seřadit zprávy nebo odeslat potvrzení.

  • Když je Close zavolán na vašem kanálu, proveďte potřebnou práci k zavření relace buď ve stanoveném časovém limitu, nebo ve výchozím. To může vést k výjimkám, pokud kanál obdrží zprávu během čekání na vypršení časového limitu pro ukončení. Je to proto, že kanál bude v uzavíracím stavu, když obdrží zprávu, takže dojde k vyvolání výjimky.

  • Když je Abort volána na vašem kanálu, okamžitě ukončete relaci bez provádění vstupně-výstupních operací (I/O). Opět to může znamenat, že nic neděláte nebo může zahrnovat přerušení síťového připojení nebo některého jiného prostředku.

Viz také