Sdílet prostřednictvím


Výběr vzorce výměny zpráv

Prvním krokem při psaní vlastního přenosu je rozhodnout, které vzory výměny zpráv (nebo poslanci) jsou potřeba 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í datagramu MEP odešle klient zprávu pomocí požáru a zapomene výměnu. Oheň a zapomenutá výměna je ta, která vyžaduje potvrzení úspěšného doručení mimo pásmo. 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ů. Kanály datagramu IOutputChannel klienta implementují rozhraní a kanály datagramu služby implementují IInputChannel rozhraní.

  • 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í požadavků a odpovědí jsou vzdálená volání procedur (RPC) a požadavky GET prohlížeče. Tento model se také označuje jako polo duplexní. V tomto MEP implementují IRequestChannel klientské kanály a kanály služeb implementují 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é se mluví, je zpráva. Vzhledem k tomu, že obě strany mohou odesílat a přijímat v tomto MEP, rozhraní implementované kanály klienta a služby je IDuplexChannel.

Flowchart showing the three basic message exchange patterns
Tři základní vzory výměny zpráv. Shora dolů: datagram, požadavek-odpověď a duplexní.

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) koreluje všechny zprávy odeslané a přijaté v 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 odpovědi na požadavek, který podporuje relace, znamená, že všechny páry požadavků a odpovědí v daném kanálu vzájemně korelují. Získáte tak celkem šest poslanců, ze které si můžete vybrat:

  • Datagram

  • Odpověď požadavku

  • Duplex

  • Datagram s relacemi

  • Odpověď na žádost s relacemi

  • Oboustranný 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 relace

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á relaci termínu k označení logické abstrakce podobné připojení. Protokoly WCF s relacemi jsou podobné síťovým protokolům orientovaným na připojení a bez relacím protokolů WCF se podobají síťovým protokolům bez připojení.

V modelu objektů kanálu se každá logická relace manifestuje jako instance kanálu relace. 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.

Flowchart showing the structure of sessionless and sessionful channels

Klient vytvoří nový kanál relace a odešle zprávu. Na straně služby obdrží naslouchací proces kanálu tuto zprávu a zjistí, že patří do nové relace, takže vytvoří nový kanál relace a předá ho aplikaci (v reakci na aplikaci volající AcceptChannel v naslouchacím procesu kanálu). 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. Naslouchací proces kanálu proto vytvoří pouze jeden kanál, přes který se do aplikace doručí 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 relací.

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

Relace se s klientem spustí jednoduše vytvořením nového kanálu relace. Spustí se ve službě, když služba obdrží zprávu, která byla odeslána v nové relaci. Podobně se relace ukončí zavřením nebo přerušením kanálu relace.

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 jsou uzavřeny na odchozí straně a ne 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 se nevrátí IDuplexSessionChannel hodnota null, což znamená, že relace je již uzavřena. Pokud IInputChannel.Receive se hodnota null nevrátila, může ukončení vstupního IDuplexSessionChannel 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.

Psaní kanálů relace

Jako autor kanálu relace 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 sessionful pod vámi v zásobníku.

  • 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, který je níže uvedený, poskytne vám tento kanál také 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 kanál protokolu, který předpokládá WCF na obou stranách, můžete vyžadovat přenos TCP nebo kanál Spolehlivého zasílání zpráv a spoléhat se na jeden z nich poskytnout relaci.

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

  • Když Abort je volána ve vašem kanálu, ukončete relaci náhle bez provádění vstupně-výstupních operací. 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í:

  • U každé příchozí zprávy musí naslouchací proces kanálu zjistit relaci, do které patří. Pokud se jedná o první zprávu v relaci, naslouchací proces kanálu musí vytvořit nový kanál a vrátit ho z volání do IChannelListener<TChannel>.AcceptChannel. V opačném případě musí naslouchací proces kanálu najít existující kanál, který odpovídá relaci, a doručit zprávu prostřednictvím daného kanálu.

  • Pokud váš kanál poskytuje relaci (spolu s požadovanými zárukami doručení), může být potřeba provést některé akce, jako jsou zprávy o opětovném objednání nebo odeslání potvrzení.

  • Při Close zavolání v kanálu proveďte potřebnou práci k zavření relace buď zadaného časového limitu, nebo výchozího. To může vést k výjimkám, pokud kanál obdrží zprávu při čekání na vypršení časového limitu ukončení. Je to proto, že kanál bude v zavřeném stavu, když obdrží zprávu, aby se zobrazila.

  • Když Abort je volána ve vašem kanálu, ukončete relaci náhle bez provádění vstupně-výstupních operací. 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é