1 / 46

Windows communication foundation

Windows communication foundation. Session és példányosítás. Példányosítási módok. példányosítás. A WCF felelős egy bejövő üzenet egy adott szolgáltatás példányhoz kötéséért. Amikor egy kérés érkezik, a WCF eldönti, hogy egy létező szolgáltatás példány fel tudja-e dolgozni a kérést.

Download Presentation

Windows communication foundation

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Windows communicationfoundation Session és példányosítás

  2. Példányosítási módok

  3. példányosítás • A WCF felelős egy bejövő üzenet egy adott szolgáltatás példányhoz kötéséért. • Amikor egy kérés érkezik, a WCF eldönti, hogy egy létező szolgáltatás példány fel tudja-e dolgozni a kérést. • Ennek eldöntésére egy döntési mátrixot állít fel.

  4. Példánykezelés • Minden szolgáltatásnak van egy példánykezelési modellje. • Három ilyen modell létezik: • az „egyke” (single), amelyben egyetlen CLR objektum szolgálja ki az összes klienst; • a „hívásonkénti” (per call), melyben minden egyes klienshívás kiszolgálására új CLR-objektum jön létre; • és a „munkamenetenkénti” (per session), melynél minden egyes munkamenethez egy kiszolgáló CLR objektum jön létre. • A példánykezelési modell kiválasztása függ az alkalmazás által támasztott követelményektől és a szolgáltatás tervezett használatától.

  5. Példánykezelés 2. • A példányosítás módjának meghatározása a szolgáltatás oldalon történik, azon belül is a szolgáltatás viselkedésének (Service Behavior) leírójában. • Ez azt jelenti, hogy a szolgáltatás összes végpontjában ugyanez a példányosítási mód lesz érvényes.

  6. Hívásonkénti (per call) mód

  7. Hívásonkénti (per call) mód • Hívásonként módban minden egyes kérésnek saját szolgáltatás példánya van. • A kliens egy proxyn keresztül intéz kéréseket a szolgáltatás felé. • Amikor a kérés megérkezik a szolgáltatás hoszthoz, a hoszt a szolgáltatást implementáló osztályból létrehoz egy új példányt. • Miután a kérés befejeződött és a válasz is visszaküldésre került a kliens felé, a példányra már nincs szükség. • Minden szolgáltatás leíró osztálynak implementálni kell az IDisposable interfészt. Amikor az adott példány elvégezte a dolgát, meghívódik a Dispose metódus.

  8. Hívásonkénti (per call) mód • A WCF-ben a hívásonkénti mód az alapértelmezett. • Ennek egyik oka, hogy így a fejlesztőnek nem kell foglalkoznia a konkurens feldolgozással. • Viszont számos hátránya is van ennek a módnak: • Teljesítmény szempontjából nem előnyös • Ha egy szolgáltatás példány zárol egy erőforrást a teljes életciklusa idejére, akkor az az erőforrás a többi példány számára elérhetetlenné válik. (pl. fájl, adatbázis, stb.) • A problémák kiküszöbölésére léteznek megoldások.

  9. Hívásonkénti (per call) mód • Az egyik megoldás egy proxy objektum rendelése a szolgáltatáshoz. • Az alapértelmezett programozási modell szerint, ha egy adott szolgáltatás példányra nincs szükség, akkor arra meghívódik a Dispose metódus. Ez érvényteleníti a referenciát, ami nem mindig kívánatos. • A WCF-ben a kliens a proxyra tart fent egy referenciát, ami nem szűnik meg minden hívás után. • A proxy feladata az, hogy a szolgáltatás példányt újra létrehozza, ha szükséges.

  10. Hívásonkénti (per call) mód • A példányosítási mód megadási a szolgáltatás oldalán történik: [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)] classUpdateService: IUpdateService{...} • Habár elméletben a kliensnek nem kell tudnia a példányosítás módjáról, a hívásonkénti példányosítási mód azt jelenti, hogy a hívások között nem őrződik meg az állapot. • Ha bármilyen okból mégis szükség van az állapot megőrzésére, a szolgáltatás feladat biztosítani azt. (pl. adatbázisba mentés)

  11. Munkamenetenkénti (per session) mód

  12. Munkamenetenkénti (per session) mód • Az előbbiekben már felmerült az igény a hívások között az állapotok megőrzésére, így létezik egy munkamenetenkénti (per session) példányosítási mód is. • A WCF képes egy privát session-t létesíteni a kliens és a szolgáltatás példány között. • Minden klienshez az első kérésekor hozzárendelődik egy szolgáltatás példány és elkezdődik egy munkamenet. • Minden további kérés ennek a munkamenetnek a része lesz, és ugyanaz a szolgáltatás példány fogja végrehajtani azt.

  13. Munkamenetenkénti (per session) mód • A munkamenetenkénti mód beállításához 2 dolog szükséges: • A szerződés rögzíti, hogy szükséges a munkamenet. Ez azért fontos, mert a kliensnek tartalmazni kell egy azonosítót, hogy megtalálja az adott szolgáltatás objektumot. • A munkamenetenkénti mód beállítása a szolgáltatás oldalon: [ServiceContract(SessionMode = SessionMode.Required)] publicinterfaceIUpdateService { // Interfacedefinitioncodegoes here }

  14. Munkamenetenkénti (per session) mód • A másik dolog: • A WCF-nek is meg kell mondani, hogy munkamenetenkénti módot szeretnénk használni, és a szolgáltatás példányt tartsa meg az egész munkamenet alatt. • Ennek megadása a következőképpen történik: [ServiceBehavior(InstanceContextMode = InstanceContextMode.PerSession)] publicclassUpdateService : IUpdateService { // Implementationcodegoes here }

  15. Munkamenetenkénti (per session) mód • A kapcsolat igazából nem a kliens és a szolgáltatás között áll fenn, hanem egy adott proxy példány között, amit a kliens és a szolgáltatás használ. • Amikor a WCF-ben létrehozunk egy proxyt, annak lesz egy azonosítója, amit a szolgáltatás hoszt arra használ, hogy a kéréseket a megfelelő példányokhoz továbbítsa. • Mivel ez az azonosító a proxy példányhoz rendelt, így ha a kliens egy proxyból több példányt is létrehoz, azok nem alkotnak egy munkamenetet. Minden proxynak saját szolgáltatás példánya lesz.

  16. Munkamenetenkénti (per session) mód • Ahogy már korábban említettük, a szolgáltatás példány addig létezik, amíg a kliensnek szüksége van rá. • Egy munkamenet megszűnésének legtermészetesebb módja, amikor a kliens bezárja a proxyt. • Ekkor egy üzenet kerül elküldése a szolgáltatás felé, hogy a munkamenet lezárult. • De mi van akkor, ha valamilyen okból a kliens nem zárja be a proxyt? • Ebben az esetben a munkamenet 10 percnyi inaktivitás után automatikusan megszűnik. Ezután ha a kliens újra használni szeretné a proxyt, CommunicationObjectFaultedException –t kap.

  17. Munkamenetenkénti (per session) mód • Ez a 10 perc csak egy alapértelmezett érték, a kötéstől függően változhat. • Ha a kötés egy megbízható munkamenetet (reliable session) biztosít, akkor az InactivityTimeout tulajdonságot ennek megfelelően átállíthatjuk. • Erre egy példa: NetTcpBindingbinding = newNetTcpBinding(); binding.ReliableSession.Enabled = true; binding.ReliableSession.InactivityTimeout = TimeSpan.FromMinutes(60);

  18. Munkamenetenkénti (per session) mód • Ugyanezt a config fájlban is megtehetjük: <netTcpBinding> <binding name="timeoutSession"> <reliableSession enabled="true„inactivityTimeout="01:00:00"/> </binding> </netTcpBinding> • Az InactivityTimeout –ot mind a kliens, mind a szolgáltatás oldalán beállíthatjuk, a kettő közül mindig a kisebb érték a mérvadó. • A basicHttpBinding nem támogatja a munkamenetek létrehozását.

  19. Singleton mód

  20. Singleton mód • Ebben a módban csak egyetlen szolgáltatás példány jön létre. • Ennek az egy példánynak a feladata az összes szolgáltatás felé beérkező kérés feldolgozása. • Az a példány örökké él, és csak akkor szűnik meg, amikor a hoszt processz bezáródik. • Beállítása: [ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)] publicclassUpdateService : IUpdateService { // Implementationcodegoes here }

  21. Singleton mód • Singleton módban lehetőség nyílik konstruktoron keresztül inicializálni a példányt. • Arra is lehetőség van, hogy létrehozzuk a szolgáltatás példányt, még mielőtt a hoszt elindul. Induláskor átadjuk ezt a példányt a hosztnak. • A ServiceHost osztály egyik konstruktora egy singleton példányt vár paraméterként. Az így létrehozott hoszt az összes kérést a paraméterében megkapott szolgáltatás példányhoz fogja továbbítani. • Ennek megadása: SingletonUpdateServicesingletonInstance = new SingletonUpdateService(); ServiceHosthost = new ServiceHost(singletonInstance); host.Open();

  22. Singleton mód • Ilyen módban más objektumoknak lehetőségük van arra, hogy elérjék a szolgáltatás példány metódusait és beállítsák a paramétereit. • A ServiceHost osztály ehhez biztosít egy SingletonInstanceproperty-t, ami az adott példányra hivatkozik. SingletonUpdateService instance = host.SingletonInstance as SingletonUpdateService; instance.Counter+= 50;

  23. Singleton mód • Ha a lokális hoszt változó nem elérhető, a példány akkor is elérhető. Az OperationContext osztály biztosít egy readonlyHostproperty-t, amiből ugyanúgy elérhető a példány. ServiceHosthost = OperationContext.Current.HostasServiceHost; if(host != null) { SingletonUpdateServiceinstance = host.SingletonInstanceasSingletonUpdateService; if(instance != null) instance.Counter+= 1; }

  24. Singleton mód • Ha minden kérést egyetlen példány szolgál ki, akkor oda kell figyelni a konkurrens hozzáférésre. • Ha egy szolgáltatáshoz egyszerre több kérés érkezik, ugyanaz a példány fogja őket feldolgozni, csak különböző szálakon. • Ez azt jelenti, hogy az aktuális metóduson kívüli összes változót (az osztály adattagjait) egyszerre több szál is módosíthatja, aminek hatására az értékük nem lesz megfelelő. • Ennek elkerülésére különböző technikákat érdemes használni, mint pl. zárolás.

  25. munka a példányokkal

  26. A szolgáltatás megvédése • Amikor egy szolgáltatás kikerül egy valós közegbe, akarva – akaratlanul is érhetik támadások. • „Denialof Service” (DoS) támadás: kimeríti a szolgáltatás erőforrásait, hogy az több bejövő kérést már ne tudjon feldolgozni. • A WCF az ilyen problémák enyhítésére számos megoldást nyújt: pl. a bejövő kérések lelassításával, gátolásával vagy erőforrás kvótákkal

  27. Bejövő kérések gátolása • Ennek a megoldásnak a célja kétszeres. • Először is megvédi a szolgáltatást attól, hogy a kliensek elárasszák kérésekkel. • Másrészt pedig egyenletes terhelés elosztást biztosít a szolgáltatásnak. • Ezt úgy valósítják meg, hogy korlátozzák a szolgáltatáshoz beérkezhető kérések számát azért, hogy azokat a szolgáltatás belátható időn belül fel tudja dolgozni. • A WCF alapbeállítása, hogy nem gátolja a bejövő kéréseket. • Ha a gátolás engedélyezett, akkor a WCF minden egyes bejövő kérésnél ellenőrzi a számlálót.

  28. Bejövő kérések gátolása • A WCF alapbeállítása, hogy nem gátolja a bejövő kéréseket. • Ha a gátolás engedélyezett, akkor a WCF minden egyes bejövő kérésnél ellenőrzi a számlálót. • Ha túllépte a beállított értéket, akkor a tovább kéréseket egy várakozó sorra teszi. • Amint a számláló értéket a küszöbérték alá csökken, sorra veszi a következőt a várakozási sorról olyan sorrendben, ahogy a kérések beérkeztek. • Általában ha a szolgáltatás elérte a maximális értékét, akkor a kliens requesttimeout-ot kap.

  29. Bejövő kérések gátolása • A szolgáltatás leírójában 3 beállítás kontrollálja a szolgáltatás által egy időben feldolgozható kérések számát. • Ezek mindegyike a config file ServiceThrottlingBehavior részében található. • Ezek a következők: • MaxConcurrentCalls: szabályozza az egyszerre feldolgozható kérések számát. Alapértéke 16. Ez az érték minden típusú kérésre érvényes. • MaxConcurrentSessions: szabályozza a sessiont igénylő csatornák maximális számát. Alapértéke 10. Ezen túli session igénylés TimeoutExepction-t dob. Ha a beérkező kérés típusa nem alkalmas session kezelésre (pl. basicHttpBinding), akkor ennek az értéknek nincs jelentősége. • MaxConcurrentInstances: a szolgáltatás példányok maximális számát adja meg. Alapértéke Int32.MaxValue. Ennek hatása a példányosítás módjától függ. Munkamenetenkénti esetben a MaxConcurrentSession érték a mérvadó, Singleton módban pedig az érték mindig 1.

  30. Bejövő kérések gátolása • Beállítása a config fájlban: <behaviors> <serviceBehaviors> <behaviorname="throttlingBehavior"> <serviceThrottlingmaxConcurrentCalls="10" maxConcurrentInstances="10" maxConcurrentCalls="10" maxConcurrentInstances="10" maxConcurrentSessions="5"/> </behavior> </serviceBehaviors> </behaviors>

  31. Bejövő kérések gátolása • Beállítás kódból: ServiceHosthost = newServiceHost( typeof(UpdateService),newUri("http://localhost:8080/UpdateService")); host.AddServiceEndpoint( "IUpdateService",newWSHttpBinding(), String.Empty); ServiceThrottlingBehaviorthrottlingBehavior = newServiceThrottlingBehavior(); throttlingBehavior.MaxConcurrentCalls= 10; throttlingBehavior.MaxConcurrentInstances = 10; throttlingBehavior.MaxConcurrentSessions = 5; host.Description.Behaviors.Add(throttlingBehavior); host.Open();

  32. Bejövő kérések gátolása • A szolgáltatás hoszt megnyitása után lehetőség van a bejövő kérések gátolási beállításainak megtekintésére, de azok módosítására nem. • Ezt a szolgáltatás diszpécserén keresztül tehetjük meg. • A ServiceHost osztály a ChannelDispatcherspropertyjében diszpécserek egy kollekcióját biztosítja, amely ChannelDispateched objektumokat tartalmaz. • A ChannelDispatcher objektumnak van egy ServiceThrottle tulajdonsága. Ezen a ServiceThrottle objektumon keresztül elérhetőek az összes beállítások.

  33. Bejövő kérések gátolása • A beállítások elérése a következőképpen történik: ChannelDispatcherdispatcher = OperationContext.Current.Host.ChannelDispatchers[0] asChannelDispatcher; ServiceThrottlethrottle = dispatcher.ServiceThrottle; Trace.WriteLine(String.Format("MaxConcurrentCalls = {0}", throttle.MaxConcurrentCalls)); Trace.WriteLine(String.Format("MaxConcurrentSessions = {0}", throttle.MaxConcurrentSessions)); Trace.WriteLine(String.Format("MaxConcurrentInstances = {0}", throttle.MaxConcurrentInstances));

  34. kvóták • A kvóta mechanizmus magában foglalja a szolgáltatás által felhasznált memória menedzselését is. • A DoS lényege, hogy hatalmas mennyiségű memóriát emészt fel, így a szolgáltatás már nem tudja kiszolgálni a további bejövő kéréseket, melyek így OutOfMemoryException vagy StackOverflowException kivételeket kapnak. • Amikor beállítunk egy kvóta értéket, QuotaExceededException keletkezik. • Ahelyett, hogy ilyenkor a szolgáltatás leállna, csak szimplán figyelmen kívül hagyja az üzenetet, és megy tovább.

  35. kvóták • Számos beállítás van hatással a kvótára: • MaxReceivedMessageSize: ez közvetlenül a kötésre állítódik be. Megadja, hogy mekkora lehet egy üzenet mérete. Alapértéke 65536 byte. Értékét akár a config fájlból, akár kódból is beállíthatjuk. • Config fájlból: <bindings> <netTcpBinding> <bindingname="netTcp„ maxReceivedMessageSize="128000"/> </netTcpBinding> </bindings>

  36. kvóták • Kódból: NetTcpBindingbinding = newNetTcpBinding(); binding.MaxReceivedMessageSize = 128000; ServiceHosthost = newServiceHost( typeof(UpdateService), newUri("net.tcp://localhost:1234/UpdateService")); host.AddServiceEndpoint( "IUpdateService",binding, String.Empty); host.Open();

  37. kvóták • ReaderQuotas: a kötés ezen tulajdonsága a beérkező üzenetek komplexitásának mértékét határozza meg. • Beállítható tulajdonságok:

  38. Műveletek elhatárolása • Alapértelmezetten egy session csak azt jelenti, hogy a szolgáltatás meg tudja állapítani, hogy melyik klienstől érkezett a kérés. • Azonban vannak esetek, amikor a műveletek végrehajtási sorrendje is számít. • A WCF biztosít erre egy mechanizmust a szerződés tervezőjének, mellyel megadhatja, hogy mely metódusok nem lehetnek elsők, vagy utolsók. Erre az IsInitiating és az IsTerminatingpropertyk szolgálnak, melyeket a OperationContract attribútumon belül állíthatunk. • Ha egy metódus IsInitiating attribútum értéke true, és még nem jött létre session, a metódus hívásakor, akkor egyből létrejön egy. Ha már létezik session, akkor a metódus azon belül hívódik meg.

  39. Műveletek elhatárolása • Ha a metódus IsTerminating attribútum értéke true, amikor a metódus befejezi futását, a session lezárul. Ez még nem jelenti azt, hogy megszűnik a szolgáltatás példány, a kliensnek ettől függetlenül még meg kell hívniuk a proxy Close metódusát. Habár minden további utasítás efelé a proxy felé InvalidOperationException-nel tér vissza. • Ezekkel a propertykkel beállítható a műveletek kezdő és végpontja. • Az IsInitiating alapértéke true, az IsTerminating alapértéke false.

  40. Műveletek elhatárolása • Beállítása: [ServiceContract(SessionMode = SessionMode.Required)] publicinterfaceIProcessOrders { [OperationContract] voidInitializeOrder(int customerId); [OperationContract(IsInitiating=false)] voidAddOrderLine(stringproductId, int quantity); [OperationContract(IsInitiating=false)] doubleGetOrderTotal(); [OperationContract(IsInitiating=false, IsTerminating=true)] boolSubmitOrder(); }

  41. Példány deaktiválása

  42. Példány deaktiválása • Ahogy az előző ábrán is látható, egy példány egy Context objektumon belül töltődik be, és a session információk a kliens üzeneteit nem közvetlenül a példányhoz kötik, hanem a Context objektumhoz. • Amikor egy session létrejön, akkor a szolgáltatás hoszt egy új kontextust készít. • Ez a kontextus megszűnik, ha a session megszűnik. • Ez azt jelenti, hogy alapértelmezetten az kontextus addig él, ameddig a benne lévő példány. • A WCF lehetőséget nyújt arra, hogy a két életciklust különválasszuk.

  43. Példány deaktiválása • Létrehozható olyan kontextus is, amiben nincs egyetlen példány sem. • A kontextus deaktiváció menedzselése az OperationBehaviorReleaseInstanceModepropertyjén keresztül történik. • A ReleaseInstanceMode-ban számos érték beállítható: • BeforeCall • AfterCall • BeforeAndAfterCall • None • Az alapértelmezett érték a None. Ez azt jelenti, hogy a szolgáltatás példány azután is létezik, miután feldolgozta a kérést.

  44. Példány deaktiválása • BeforeCall mód esetén minden kérés előtt új példány jön létre. Ha egy példány már eleve létezik, akkor deaktiválódik és meghívódik rá a Dispose metódus. Ezalatt a kliens blokkolódik. Az a mód általában akkor használatos, ha a metódus egy kritikus erőforráshoz szeretne hozzáférni és biztosnak kell lenni abban, hogy az összes előző hozzáférés törlődött. • AfterCall mód esetén a metódus lefutása után az aktuális példány deaktiválódik és meghívódik rá a Dispose metódus. Ezzel azt biztosíthatjuk, hogy a metódus által használt erőforrást azonnal felszabadítjuk, amint nincs már rá szükség, így a következő hívásnál egyből elérhető lesz.

  45. Példány deaktiválása • BeforeAndAfterCall mód esetén a mód az előbbi kettő ötvözése. Gyakorlatilag ugyanaz, mint a hívásonkénti (per call) példányosítási mód. A különbség csak annyi, hogy ezt a módot metódusonként tudjuk beállítani, így minden egyes metódusra más és más lehet a példányosítási mód. • Beállítása: publicclassUpdateService : IUpdateService { [OperationBehavior(ReleaseInstanceMode=ReleaseInstanceMode. BeforeAndAfterCall)] publicvoid Update() { // Implementationcodegoes here } }

  46. Példány deaktiválása • Lehetőség van az aktuális szolgáltatás példány futásidejű deaktiválására is. • Ehhez az kontextus biztosít egy ReleaseServiceInstance metódust. • Amikor ezt meghívódik, az aktuális példány megjelölésre kerül, hogy rá a deaktiválás vár, miután a metódus befejezte a futását. • Meghívása: OperationContext.Current.InstanceContext.ReleaseServiceInstance();

More Related