1

WCF pro začátečníky – 2. díl: contract, binding, service behavior

autor Kryštof Laryš | publikováno 13. února 2009


Vítám vás u dalšího dílu seriálu. Dnes se podíváme podrobněji na pojmy, jako jsou kontrakty (contracts), bindings, instancing a zmíníme se o pojmech souvisejících s nastavením chování služeb (service behavior).

V minulém díle jsme si vysvětlili, co contract znamená, že je nezávislý na bindingu a adrese a že se definuje na službě. Nyní se podíváme, jaké máme typy contractů, kdy a kde je použít. Máme čtyři základní typy contractů:

  • service contract (kontrakt služby)
  • data contract (kontrakt dat)
  • message contract (kontrakt zpráv)
  • fault contract (kontrakt chyb)

Jsou ale ještě i jiné důležité kontrakty, například collection contract, ale tím se teď nebudeme zabývat.

Service contract definuje operace, které může klient vykonávat. Označuje se atributem [ServiceContract], který se přidá před rozhraní nebo třídu. Jednotlivé metody se označí atributem [OperationContract] a klient tak ví, které metody může používat. Příklad:
 

				[ServiceContract]
public interface IService1
{
    [OperationContract]
    string GetData(string value);

    [OperationContract]
    void Delete(int code);
}


Data contract
definuje, které datové typy se budou posílat z/do služby. Popisuje strukturu těchto přenášených dat. Pokud chceme posílat jiné typy, než například int, string, musíme definovat data contract. Ten označíme atributem [DataContract] před třídou, případně strukturou, výčtovým typem. Jednotlivé členy data contractu pak označíme jako [DataMember]. Příklad:
 

				[DataContract]
public class MyClass
{
    private string stringValue = "Hi folks";
    private bool boolValue = true;

    [DataMember]
    public bool BoolValue
    {
        get { return boolValue; }
        set { boolValue = value; }
    }

    [DataMember]
    public string StringValue
    {
        get { return stringValue; }
        set { stringValue = value; }
    }
}


Message contract
popisuje strukturu SOAP zprávy a může být typový či netypový. Umožňuje specifikovat, zda zpráva půjde do hlavičky nebo těla zprávy. Na rozdíl od data contracts jsou message contracts určené pro specifikaci operace služby a nejsou určené pro znovupoužití a sdílení. Message contract definujeme přidáním atributu [MessageContract] k deklaraci třídy. Jednotlivé části zprávy definujeme atributy [MessageHeader] jako hlavičku a [MessageBody] jako tělo zprávy. Message contract je z těchto tří kontraktů asi nejméně využívaný a ani já ve svých příkladech jej nebudu nijak hojně používat. Příklad:
 

				[MessageContract]
public sealed class MyClass
{
    private string jmeno;
    private string prijmeni;

    [MessageHeader]
    public string Jmeno
    {
        get { return jmeno; }
        set { jmeno = value; }
    }

    [MessageBody]
    public string Prijmeni
    {
        get { return prijmeni; }
        set { prijmeni = value; }
    }
}


Fault contract
definuje, které chyby budou službou vyvolány a jak budou zasílány klientovi, zdali se budou vůbec posílat. Zpracování výjimek budeme řešit v samostatném díle.

Opět navážu na minulý díl, kde jsem se zmínil o bindingu. Vysvětlíme si jej podrobněji. Binding je tvořen následujícími složkami:

  • transport (komunikační protokol)
  • encoding (text, binary, ...)
  • security
  • reliable sessions
  • transakce 

Všechny tyto části jsou tak rozsáhlé, že každé z nich bude věnován jeden díl seriálu. Dnes se ale podíváme na základní složku, a tou je transport. V této složce vybíráme protokol, který použijeme pro komunikaci služby s klienty. Příklady těch nejdůležitějších protokolů a jejich vlastnosti:

 

Binding

 Interop.1

 Security

 Session

Trans.2 

Duplex 

 Encoding

BasicHttpBinding

Basic Profile 1.1

Transport,
Message,
Mixed

Ne

Ne

 

Text

WSHttpBinding

WS

Transport,
Message,
Mixed

Transport, Reliable Session

Ano

 

Text

WSDualHttpBinding

WS

Message

Reliable Session

Ano

Ano

Text

WSFederationHttpBinding

WS-Federation

Message,
Mixed

Reliable Session

Ano

Ne

Text

NetTcpBinding

.NET

Transport,
Message,
Mixed

Transport, Reliable Session

Ano

Ano

Binary

NetNamedPipeBinding

.NET

Transport

Transport

Ano

Ano

Binary

NetMsmqBinding

.NET

Transport,
Message

Ne

Ano

Ne

 

NetPeerTcpBinding

Peer

Transport

Ne

Ne

Ano

 

MsmqIntegrationBinding

MSMQ

Transport

Ne

Ano

 

 

1Interoperability
2Transactions


BasicHttpBinding
– pro komunikaci webových služeb splňujících WS-Basic Profile
WSHttpBinding – zabezpečený a interoperabilní binding bez podpory duplex kontraktů
WSDualHttpBinding – s podporou duplex kontraktů
WSFederationHttpBinding – podpora protokolu WS-Federation
NetTcpBinding – zabezpečený a optimalizovaný binding pro komunikaci WCF aplikací (velmi využívané)
NetNamedPipeBinding – komunikace WCF aplikací v rámci jednoho PC (velmi rychlé)
NetMsmqBinding – komunikace pomocí MSMQ (message queue – velmi spolehlivé doručování zpráv, často používané)
NetPeerTcpBinding – vícepočítačová komunikace
MsmqIntegrationBinding – komunikace mezi WCF aplikací a již existující MSMQ aplikací

V případě, že by vám žádný z nabízených bindingů nevyhovoval, můžete si vytvořit i vlastní (custom binding).

Podle čeho vybírat binding, který použijeme? Základní úvaha je taková, že si musíme uvědomit, jestli bude komunikovat služba s klientem tak, že oba tyto programy jsou napsány pomocí technologie WCF. Blíže to vysvětluje následující obrázek:

Poslední část tohoto dílu je věnována service behavior neboli chování služby. V nastavení chování služby se toho dá nastavit opravdu spoustu. Opět budeme rozebírat jednotlivé části postupně v dalších dílech, dnes se podíváme jen na tři první z nich. Co můžeme nastavit v service behavior:

  • Instancing – nastavení způsobu vytváření instancí tříd služby
  • Concurrency – nastavení vztahu vláken a instancí
  • Throttling – nastavení limitu současně existujících instancí, session a volání
  • Error handling – nastavení zpracovávání chyb
  • Metadata – nastavení poskytování metadat
  • Session – nastavení vytváření session
  • Security – nastavení zabezpečení služby
  • Transactions – nastavení transakčního vykonávání operací služby

Instancing
WCF nám nabízí tři módy vytváření instancí tříd služby:

  • per call – každá instance třídy služby je při každém požadavku klienta vytvořena a následně zrušena (použijeme, pokud nechceme uchovávat stav mezi voláním jednotlivých operací)
  • per session – nová instance služby je vytvořena pro každé nové session klienta (vznik nového klientského kanálu), stav je tedy uchován po dobu trvání session (použijeme, pokud chceme pro každého klienta uchovávat stavy po dobu trvání jejich práce se službou)
  • single – existuje jen jedna instance služby, která obsluhuje požadavky všech klientů (použijeme, pokud chceme, aby všichni klienti pracovali se společnými hodnotami – sdílí se mezi nimi stav)

Concurrency
Nastavujeme v případě, že k instanci služby bude přistupovat více vláken. Máme na výběr tyto tři módy:

  • single – v daném okamžiku k instanci služby může přistupovat pouze jedno vlákno
  • reentrant – stejně, jako u single, ale jsou povolena i znovuvstupující zpětná volání (využije se tehdy, když vlákno první služby volá druhou službu a vlákno druhé služby zpět volá první službu)
  • multiple – v daném okamžiku k instanci služby může přistupovat více vláken

Throttling
Díky tomuto nastavení můžeme vymezit, kolik systémových zdrojů služba zabere. Nastavit můžeme například:

  • maximální množství současných volání pro instanci služby
  • maximální množství současně existujících sessions
  • maximální množství současně existujících instancí služby

V následujícím díle seriálu si mimo jiné ukážeme i praktickou ukázku toho, jak si vytvořit jednoduchou službu, hostovací aplikaci a klientskou aplikaci.


Kryštof