20. Vytváření více vrstvových aplikací

Více vrstvová aplikace Klient/server je rozložena do logických jednotek, které jsou spuštěny společně na samostatných počítačích. Více vrstvové aplikace sdílejí data a komunikují s jinými, prostřednictvím lokální sítě nebo prostřednictvím Internetu. To poskytuje mnoho výhod, jako je centralizovaná logika řízení a aplikace tenkého klienta.
Ve své nejjednodušší formě, někdy nazývané třívrstvový model, více vrstvová aplikace je rozbělena na:

V tomto třívrstvovém modelu aplikační server spravuje tok dat mezi klientem a vzdáleným databázovým serverem a někdy jej nazýváme Datový agent. Pomocí C++ Builderu obvykle vytváříme pouze aplikační server a jeho klienty, i když by bylo také možno vytvořit vlastní databázi.
Ve složitějších více vrstvových aplikacích, další služby sídlí mezi klientem a vzdáleným databázovým serverem. Např. zde mohou být bezpečnostní služby agenta k zajištění bezpečnosti Internetovských transakcí nebo most ke zpracování sdílených dat na databázových platformách, které nejsou přímo podporované C++ Builderem.
C++ Builder podporuje více vrstvové aplikace založené na MIDAS (Multi-tier Distributed Application Services Suite). V části Seznámení s technologií MIDAS je poskytnut úvod do této technologie a je zde popsána architektura třívrstvových aplikací používající MIDAS. Když již pochopíme jak vytvářet a spravovat třívrstvové aplikace, pak můžeme vytvářet a přidávat další služební vrstvy podle potřeby.
Po pochopení základů technologie přejdeme do části Budování více vrstvových aplikací, kde se seznámíme podrobněji s vytvářením více vrstvových aplikací.
Architektura MIDAS může být kombinovaná s podporou C++ Builderu pro budování ovladačů ActiveX k distribuování klientských aplikací jako ovladačů ActiveX.

Výhody více vrstvového modelu databáze

Model více vrstvové databázové aplikace rozděluje databázovou aplikaci do logických částí. Klientská aplikace se zaměřuje na zobrazování dat a interakci s uživatelem. V ideálním případě nemusí znát nic o uložení dat a jejich údržbě. Aplikační server (střední vrstva) koordinuje a zpracovává požadavky a aktualizace od více klientů. Zpracovává všechny detaily datových množin a interakci se vzdáleným databázovým serverem.
Výhody více vrstvového modelu zahrnují:

Seznámení s technologií MIDAS

MIDAS poskytuje mechanismus, kterým klientská aplikace a aplikační server komunikují s databázovými informacemi. Použití MIDAS požaduje DBCLIENT.DLL, používanou klientskou i serverovou aplikací pro správu datových množin uložených jako datové pakety. MIDAS také zahrnuje Průzkumník SQL pro pomoc v administraci databáze a k importu serverových omezení do Datového slovníku a tak mohou být testovány na libovolné úrovni více vrstvové aplikace. Můžeme také požadovat použití OLEnterprise, což poskytuje služby založené na COM (Business Object Broker), pro transparentnost umístění a balancování zavádění.
Více vrstvová aplikace založená na MIDAS používá komponenty ze stránky MIDAS Palety komponent, plus vzdálené datové moduly, které vytvoříme průvodcem na stránce Multitier dialogového okna New Items. Tyto komponenty jsou popsány v následující tabulce:
 
Komponenta Popis
vzdálené datové moduly Specializované datové moduly, které pracují se Serverem automatizace COM pro zpřístupnění libovolného poskytovatele, který obsahuje klientskou aplikaci. Používáno na aplikačním serveru.
komponenta poskytovatele Datový agent, který poskytuje data vytvářením datových paketů a řešící aktualizace klienta. Tyto služby jsou prováděny prostřednictvím rozhraní IProvider. Používáno na aplikačním serveru.
komponenta klientské datové množiny Specializovaná datová množina používající DBCLIENT.DLL místo BDE pro správu dat uložených v datových paketech.
komponenty připojení Rodina komponent, které sídlí na serveru a dělá rozhraní IProvider dostupným z klientských datových množin. Každá komponenta připojení je specializovaná k použití jistého komunikačního protokolu.

Více informací jak tyto komponenty použít k vytvoření více vrstvové aplikace najdeme v bodech:

Úvod do více vrstvových aplikací založených na MIDAS

Následující očíslované kroky ukazují normální sekvenci činností pro více vrstvové aplikace založené na MIDAS:
  1. Uživatel spustí klientskou aplikaci. Klient se připojí k aplikačnímu serveru (který může být specifikován při návrhu nebo za běhu). Pokud aplikační server ještě není spuštěn, pak je spuštěn. Klient získá rozhraní poskytovatele od aplikačního serveru.
  2. Klient požaduje data od aplikačního serveru. Klient může požadovat všechna data najednou, nebo je může požadovat po malých částech prostřednictvím sezení.
  3. Aplikační server získá data (nejprve v případě nutnosti zřídí databázové připojení), balí je pro klienta a vrací datový paket klientovi. Další data (např. datová omezení požadovaná databází) mohou být vložena do metadat datového paketu. Tento proces balení dat do datových paketů se nazývá poskytování.
  4. Klient dekóduje datový paket a zobrazí data uživateli.
  5. Jak uživatel pracuje s klientskou aplikací, data jsou aktualizována (záznamy jsou přidávány, rušeny nebo modifikovány). Tyto modifikace jsou ukládány v deníku změn klienta.
  6. Klient může aplikovat své aktualizace na aplikační server, obvykle v reakci na akci uživatele. Pro aplikování aktualizací, klient zabalí svůj deník změn a zašle jej jako datový paket na server.
  7. Aplikační server dekóduje balíček a odešle aktualizace v kontextu transakce. Pokud záznam nemůže být odeslán na server (např. protože jiná aplikace změnila záznam po jeho předání klientovi a před aplikováním jeho změn), pak aplikační server se pokusí "smířit" změny klienta se současnými daty nebo tento záznam odložit. Proces odesílání záznamů a odkládání problémových záznamů se nazývá řešení.
  8. Když aplikace dokončí proces řešení, vrátí nevyřešené záznamy klientovi pro další řešení.
  9. Klient se pokusí vyřešit zbývající problémy. Je mnoho způsobů jak to klient může provést. Obvykle klient se pokusí opravit situaci a zabránit zrušení změn. Pokud chyby jsou opraveny, pak klient je aplikuje znova.
  10. Klient obnovuje svá data ze serveru.

Struktura klientské aplikace

Z hlediska koncového uživatele, klientská aplikace více vrstvové aplikace vypadá a chová se jinak než tradiční dvouvrstvová aplikace. Strukturálně klientská aplikace vypadá jako jednovrstvová aplikace plochých souborů. Interakce uživatele probíhá prostřednictvím datových ovladačů, které zobrazují data z komponenty klientské datové množiny.
Na rozdíl od aplikací plochých souborů, klientská datová množina ve více vrstvových aplikacích získává svoje data prostřednictvím rozhraní na aplikačním serveru. Toto rozhraní také používá k odesílání aktualizací na aplikační server. Ve většině případů je to rozhraní IProvider. Klient získá toto rozhraní od komponenty připojení.
Poznámka: Když používáme MTS, pak můžeme zvolit nepoužívání rozhraní IProvider našimi klientskými datovými množinami. Zápisem kódu k poskytnutí dat do a k aplikování aktualizací z klientské datové množiny bez použití rozhraní IProvider, naše MTS aplikace může převzít výhody služeb MTS jako jsou transakce MTS a aktivace "just-in-time". Více informací nalezneme v Používání MTS.
Komponenta připojení zřizuje připojení k aplikačnímu serveru. Pro používání různých komunikačních protokolů jsou dostupné různé komponenty připojení. Přehled komponent připojení je uveden v následující tabulce:
 
Komponenta Protokol
TDCOMConnection DCOM
TSocketConnection Sokety Windows (TCP/IP)
TOLEnterpriseConnection OLEnterprise (RPCs)

Poznámka: Další dvě komponenty připojení TRemoteServer a TMIDASConnection jsou poskytnuty pro zpětnou kompatibilitu.
Když propojení je zřízeno, pak komponenta propojení použije rozhraní IDataBroker aplikačního serveru k získání rozhraní IProvider pro libovolnou datovou množinu ve vzdáleném datovém modulu.

Struktura aplikačního serveru

Aplikační server obsahuje speciální třídy odvozené od rozhraní IDataBroker, které klientské aplikace používají k získání přístupu k poskytovateli dat. Pokud vytváříme aplikační server jako Active Library (DLL), která je instalovaná s MTS, pak tato speciální třída také spravuje rozhraní IObjectContext umožňující interakci s MTS proxy.
Mimo třídy, která podporuje rozhraní IDataBroker, aplikační server obsahuje vzdálené datové moduly, které obvykle obsahují komponentu poskytovatele k udělání každé datové množiny aplikačního serveru dostupné v klientské aplikaci. Rozhraní IProvider tedy může: Poznámka:  Pokud do aplikačního serveru nedodáme komponentu poskytovatele pro datové množiny podporující BDE, pak jedna je pro nás vytvořena dynamicky. Explicitním přidáním komponenty poskytovatele získáme větší řízení a umožníme poskytování z dalších typů datových množin.
Často poskytovatel používá datové množiny podporující BDE, které nalezneme ve dvouvrstvových aplikacích podporujících BDE. Můžeme přidat komponenty databáze a sezení podle potřeby, a to stejně jako ve dvouvrstvových aplikacích založených na BDE.
Pokud aplikační server podporuje MTS, pak vzdálený datový modul obsluhuje události, pro které aplikační server je aktivován nebo deaktivován. To umožňuje aplikačnímu serveru zřídit databázové připojení při aktivování a jeho uvolnění při deaktivování.
Používání MTS
Používání MTS umožňuje našim aplikačním serverům přebírat výhody: K převzetí výhod transakcí, aktivace just-in-time a deaktivace as-soon-as-possible, instance vzdálených datových modulů musí být beze stavové. Protože rozhraní IProvider se opírá o stavové informace, klient nemůže použít rozhraní IProvider pokud chceme  převzít výhody těchto služeb. Musíme vytvořit vlastní rozhraní pro poskytování dat a aplikování aktualizací.
Varování: Když používáme MTS, databázové připojení nemůže být otevřeno pokud vzdálený datový modul je aktivován. V průběhu vývoje naší aplikace, se musíme ujistit, že všechny datové množiny nejsou aktivní a databáze nejsou připojena před spuštěním naší aplikace. V aplikaci samotné, musí být kód pro otevření databázového připojení při aktivování datového modulu a k uzavření, když datový modul je deaktivován.
Používání rozhraní IDataBroker
Aplikační server podporuje rozhraní IDataBroker. Komponenty připojení v klientské aplikaci používají toho rozhraní k formování připojení.
IDataBroker definuje pouze jednu metodu: GetProviderNames. Komponenty připojení volají GetProviderNames k získání seznamu komponent poskytovatelů na aplikačním serveru. Klientské datové množiny se připojují k poskytovateli z tohoto seznamu, nastavením jejich vlastnosti ProviderName na jedno z těchto jmen.
Poznámka: Když klient použije GetProviderNames pro připojení klientské datové množiny k poskytovateli na aplikačním serveru, pak stav svého vzdáleného datového modulu musí být chráněn tak dlouho, dokud klient drží odkaz na rozhraní poskytovatele.
Používání rozhraní IProvider
Rozhraní IProvider je implementováno komponentou poskytovatele na aplikačním serveru. Klientské datové množiny v klientské aplikaci používají rozhraní IProvider ke komunikaci s touto komponentou poskytovatele. Většina klientských aplikací nepoužívá rozhraní IProvider přímo, ale je vyvoláváno nepřímo prostřednictvím vlastností a metod klientské datové množiny. Nicméně, když je to zapotřebí, můžeme přímo volat rozhraní IProvider pomocí vlastnosti Provider klientské datové množiny.
Následující tabulka uvádí vlastnosti a metody rozhraní IProvider, odpovídající vlastnosti a metody v TProvider, které je implementují a odpovídající vlastnosti a metody v TClientDataSet, které je používá.
 
IProvider TProvider TClientDataSet
Metoda ApplyUpdates Metoda ApplyUpdates Použito metodou ApplyUpdates
Vlastnost Constraints Vlastnost Constraints Aplikace musí použít rozhraní přímo
Vlastnost Data Vlastnost Data Vlastnost Data
Metoda DataRequest Metoda DataRequest Aplikace musí použít rozhraní přímo
Metoda Get_Constraints Vlastnost Constraints Aplikace musí použít rozhraní přímo
Metoda Get_Data Metoda Get_Data Použito k implementaci vlastnosti Data
Metoda GetMetaData Metoda GetRecords (Count = 0)  Použito interně
Metoda GetRecords Metoda GetRecords Použito metodou GetNextPacket
Metoda Reset Metoda Reset Použito interně
Metoda Set_Constraints Vlastnost Constraints Aplikace musí použít rozhraní přímo
Metoda SetParams Metoda SetParams Použito pro vlastnost Params

Poznámka: Všechny vlastnosti a mnoho metod rozhraní IProvider působí na informace o stavu ve vzdáleném datovém modulu. Z tohoto důvodu nelze použít toto rozhraní pro aplikace, které používají MTS.

Volba protokolu připojení

Každý komunikační protokol, který můžeme použít pro připojení naší klientské aplikace k aplikačnímu serveru poskytuje své vlastní unikátní výhody. Před volbou protokolu musíme zvážit kolik klientů můžeme očekávat, jak budeme šířit naši aplikaci a budoucí plány vývoje.
Následující body popisují unikátní služby každého komunikačního protokolu:
Používání připojení DCOM
DCOM poskytuje nejpřímější možnosti komunikace, nevyžadující další běžící aplikace na serveru. Nicméně, protože DCOM není obsaženo ve Windows 95, klientské počítače nemusí mít DCOM instalováno.
DCOM poskytuje pouze možnosti, které umožňují používat bezpečnostní služby MTS. Bezpečnost MTS je založena na přiřazení rolí k volajícím objektům MTS. Když voláme do MTS pomocí DCOM, pak DCOM informuje MTS o klientské aplikaci, která generuje volání. MTS pak může aktuálně určit roli volajícího. Volání DCOM do aplikačního serveru jsou v zájmu klienta.
Používání připojení Socket
Sokety TCP/IP umožňují vytvořit tenkého klienta. Např. pokud distribuujeme naší klientskou aplikaci prostřednictvím Web jako aktivní formulář, pak si nemůžeme být jisti zda klientský systém podporuje DCOM. Sokety poskytují nejnižší obecný protokol o kterém víme, že je dostupný pro připojení k aplikačnímu serveru.
Místo instantizace vzdáleného datového modulu přímo od klienta (což nastává s DCOM), sokety používají oddělenou aplikaci na serveru (ScktSrver.exe nebo ScktSrvc.exe), která akceptuje klientské požadavky a instantizuje vzdálený datový modul pomocí COM. Komponenta připojení na klientu a ScktSrvr.exe nebo ScktSrvc.exe na serveru jsou zodpovědné za řazení volání IProvider.
Když používáme sokety, pak není ochrana na serveru před chybami klientského systému před uvolněním odkazu na rozhraní na aplikačním serveru. Je to v důsledku menších provozních zpráv než při použití DCOM (kde jsou periodicky zasílány udržovací zprávy), a může to způsobit neuvolnění zdrojů na aplikačním serveru, neboť server nezjistí, že klient zdroje již nepotřebuje.
Používání OLEnterprise
OLEnterprise používá Business Object Broker namísto spoléhání se na klientskou stranu. Bussines Object Broker poskytuje vyvážené zavádění a transparentnost umístění.
Když používáme OLEnterprise, pak musíme nainstalovat jeho běhové prostředí a to na klientském i serverovém systému. OLEnterprise seřadí volání Automation a komunikace mezi klientským a serverovým systémem pomocí volání vzdálených procedur (RPC). Více informací najdete v dokumentaci OLEnterprise.

Budování více vrstvových aplikací

Obecné kroky pro vytváření více vrstvových aplikací jsou:
  1. Vytvoříme aplikační server.
  2. Registrujeme nebo instalujeme aplikační server.
  3. Vytvoříme klientskou aplikaci.
Pořadí vytváření je důležité. Musíme vytvořit a spustit aplikační server před vytvářením klienta. Při návrhu se budeme potřebovat připojit k aplikačnímu serveru pro testování našeho klienta. Můžeme ovšem vytvořit klienta bez specifikace aplikačního serveru při návrhu a za běhu pouze předat jméno serveru. Nicméně, pokud chceme vidět, zda naše aplikace pracuje jak očekáváme při kódování během návrhu, je vhodné zvolit server a poskytovatele pomocí Inspektora objektů.
Poznámka: Pokud nevytváříme klientskou aplikaci na stejném počítači jako je server a nepoužíváme připojení sokety, pak můžeme registrovat nebo instalovat aplikační server na systému klienta. Tím uděláme aplikační server dostupným při návrhu z komponenty připojení tak, že zvolíme jméno serveru a poskytovatele z rozbalovacího seznamu v Inspektoru objektů. Pokud používáme propojení sokety, pak komponenta připojení získá jména registrovaných serverů z počítače serveru.
Následující body popisují jak můžeme rozšířit základ více vrstvové architektury k podpoře speciálních požadavků naší aplikace:

Vytváření aplikačního serveru

Aplikační server vytváříme podobně jako většinu databázových aplikací. Hlavním rozdílem je to, že aplikační server obsahuje nějaký typ poskytovatele. Můžeme použít komponentu TProvider nebo TDataSetProvider nebo vlastnost Provider potomka TDBDataSet (např. TTable).
K vytvoření aplikačního serveru zahájíme nový projekt, uložíme jej a provedeme tyto kroky:
  1. Přidáme k projektu nový vzdálený datový modul. Zvolíme File | New, přejdeme na stránku Multitier a zvolíme
  2. Více informací o nastavování vzdáleného datového modulu nalezneme v Nastavování vzdáleného datového modulu.
    Poznámka: Když k našemu projektu přidáme vzdálený datový modul, pak Průvodce vytvoří také speciální objekt Automatizace COM, který obsahuje odkaz na vzdálený datový modul a používáme jej k hledání poskytovatele.
  3. Umístíme potřebné komponenty tabulek, dotazů a uložených procedur na datový modul a nastavíme na nich přístup na databázový server.
  4. Umístíme komponentu poskytovatele nebo datové množiny podporující BDE na datový modul pro přístup ke každé datové množině. Musíme explicitně exportovat každého poskytovatele v datovém modulu tím, že jej registrujeme v knihovně typů. Provedeme to tak, že vybereme postupně každou komponentu poskytovatele (TProvider, TDataSetProvider nebo TBDEDataSet) a v místní nabídce datového modulu zvolíme Export From <Name>.
  5. Pokud používáme komponentu poskytovatele, nastavíme její vlastnost DataSet na jméno zpřístupňované datové množiny. Pro poskytovatele můžeme nastavit další vlastnosti. Více informací o nastavování poskytovatele nalezneme ve Vytváření poskytovatele dat pro aplikační server.
  6. Zapíšeme kód aplikačního serveru k implementaci událostí, sdílených obchodních pravidel a sdílené bezpečnosti. Můžeme chtít rozšířit rozhraní aplikačního serveru k poskytnutí dalších způsobů volání serveru klientskou aplikací.
  7. Uložíme, přeložíme a registrujeme nebo instalujeme aplikační server.
  8. Pokud naše serverová aplikace nepoužívá DCOM, pak musíme instalovat software který přijímá klientské zprávy, instantizuje vzdálené datové moduly a řadí volání rozhraní. Pro sokety TCP/IP je to aplikace vyřizující sokety. C++ Builder je dodáván se dvěmi vyřizujícími aplikacemi: ScktSrvr.exe, jednoduchou na soketech založenou aplikací, kterou můžeme spustit na libovolném systému a ScktSrvc.exe, které je aplikací služby NT. Pro OLEnterprise je to běhové prostředí OLEnterprise.

Nastavování vzdáleného datového modulu

Když nastavujeme a spouštíme aplikační server, pak nezřizujeme žádné propojení s klientskou aplikací. K zřízení připojení na aplikační server klientská aplikace používá své komponenty připojení a obvykle je zřízeno jedno připojení k výběru poskytovatele. Vše to proběhne automaticky, bez nutnosti zapisovat kód pro správu odcházejících požadavků nebo předávání rozhraní.
Po zřízení připojení, rozhraní mezi aplikačním serverem a klientskou datovou množinou je automatické a transparentní pro vývojáře i uživatele. Připojení je udržováno klientskou aplikací.
Když vytváříme vzdálený datový modul, pak musíme poskytnout jisté informace, které indikují jak reagovat na klientské požadavky. Tyto informace se liší podle toho, zda používáme nebo nepoužíváme pro přístup na náš aplikační server, MTS. Následující body popisují jak konfigurovat vzdálený datový modul:
Konfigurování vzdáleného datového modulu nepoužívajícího MTS
K přidání vzdáleného datového modulu bez poskytnutí podpory MTS, zvolíme File | New a na stránce Multitier vybereme Remote Data Module. Tím spustíme průvodce vytvářením vzdáleného datového modulu.
Musíme dodat jméno třídy pro náš vzdálený datový modul. Je to základní jméno potomka TDataModule, kterého naše aplikace vytváří. Je také základním jménem rozhraní serverové aplikace. Např. pokud specifikujeme jméno třídy MyDataServer, pak průvodce vytvoří novou jednotku deklarující TMyDataServer, jako potomka TDataModule. V hlavičkovém souboru, Průvodce také deklaruje speciální implementační třídu (TMyDataServerImpl), potomka TDataBroker, která implementuje TMyDataServer.
Poznámka: Můžeme přidat své vlastní vlastnosti a metody k novému rozhraní. Více informací nalezneme v Rozšiřování rozhraní aplikačního serveru.
Pokud vytváříme DLL (Active Library), pak musíme v Průvodci vytvářením vzdáleného datového modulu specifikovat vláknový model. Můžeme volit z: Single-threaded, Apartment-threaded, Free-threaded nebo Both.
Konfigurování vzdáleného datového modulu používajícího MTS
K přidání vzdáleného datového modulu k naší aplikaci, když používáme MTS, zvolíme File | New a na stránce Multitier vybereme MTS Data Module. Tím spustíme Průvodce vytvářením datového modulu MTS.
Musíme předat jméno třídy pro náš vzdálený datový modul. Je to základní jméno potomka TDataModule, kterého naše aplikace vytváří. Je také základním jménem rozhraní serverové aplikace. Např. pokud specifikujeme jméno třídy MyDataServer, pak průvodce vytvoří novou jednotku deklarující TMyDataServer, jako potomka TDataModule. V hlavičkovém souboru, Průvodce také deklaruje speciální implementační třídu (TMyDataServerImpl), potomka TDataBroker, která implementuje TMyDataServer. TMyDataServerImpl obsahuje datové položky pro rozhraní IObjectContext, které můžeme použít pro správu transakcí MTS, testování bezpečnosti MTS apod.
Poznámka: Můžeme přidat své vlastní vlastnosti a metody k novému rozhraní. Musíme to udělat když chceme převzít výhody transakcí MTS nebo aktivace just-in-time. Více informací nalezneme v Rozšiřování rozhraní aplikačního serveru.
MTS aplikace jsou vždy DLL (Active Libraries). V Průvodci vytvářením datového modulu MTS musíme specifikovat vláknový model. Můžeme volit: Single, Apartment nebo Both: Poznámka: Model Apartment pod MTS se liší od odpovídajícího modelu pod DCOM.
Musíme také specifikovat atributy transakcí MTS našeho vzdáleného datového modulu. Můžeme volit z:

Vytváření poskytovatele dat pro aplikační server

Každý vzdálený datový modul na aplikačním serveru obvykle obsahuje jednu nebo více komponent poskytovatele. Komponenta poskytovatele odpovídá rozhraní IProvider, balí data do datových paketů, které jsou zasílány klientovi a aplikuje aktualizace získané od klienta. Poskytovatel pracuje ve spojení s komponentou řešitele, která zpracovává detaily řešení konfliktů dat na databázi (nebo na datové množině).
Poznámka: Místo umisťování komponent poskytovatele do vzdáleného datového modulu a jejich používání k zřízení rozhraní IProvider, které můře být používáno s klientskými datovými množinami, můžeme zvolit k použití vlastnost Provider komponenty TStoredProc, TQuery nebo TTable k překlenutí explicitního použití samostatné komponenty poskytovatele. Když použijeme vlastnost Provider komponenty datové množiny přímo, pak C++ Builder vytváří a spravuje poskytovatele pro nás za scénou.
Když použijeme komponentu poskytovatele, pak ji musíme přiřadit ke komponentě datové množiny na aplikačním serveru. Provedeme to nastavením vlastnosti DataSet poskytovatele na jméno používané datové množiny. Pokud poskytujeme z a řešíte na datovou množinu, pak můžeme použít TDataSetProvider, která pracuje s libovolným potomkem TDataSet. Pokud řešíme přímo do databáze, pak musíme použít TProvider, umožňující použít pouze datové množiny podporující BDE.
Při návrhu vybereme z dostupných datových množin ve vlastnosti DataSet v Inspektoru objektů.
Pokud vytváříme beze stavový vzdálený datový modul, pak většina práce komponenty poskytovatele probíhá automaticky. Není zapotřebí zapisovat žádný kód na poskytovateli k vytvoření plně funkčního aplikačního serveru. Používání komponenty poskytovatele dává naší aplikací více řízení nad určením jaké informace pro klienty balit a jak naše klientská aplikace reaguje na požadavky klientů.
Následující body popisují jak používat komponentu poskytovatele k řízení interakcí s klientskou aplikací:
Řízení jaké informace jsou uloženy v datových paketech
Jsou tři způsoby řízení, které informace jsou vloženy do datových paketů zasílaných ke a od klienta. Jedná se o: Specifikování které položky jsou v datových paketech
K řízení, které položky jsou vloženy do datových paketů, vytvoříme trvalé položky v datové množině, kterou poskytovatel používá k budování paketů. Poskytovatel pak vloží pouze tyto položky. Položky jejichž hodnoty jsou generovány dynamicky na serveru (jako jsou počitatelné nebo vyhledávací položky) mohou být vloženy, ale zobrazí se na konci klientské datové množiny jako statické položky určené pouze pro čtení.
Pokud klientská datová množina bude editována a aktualizace aplikovány na aplikační server, pak musíme vložit položky určující záznam v datovém paketu. Jinak při aplikování aktualizace nemusí být možno určit, který záznam aktualizovat. Pokud nepožadujeme aby klientská datová množina byla schopna vidět nebo používat speciální položky poskytnuté pouze k zajištění unikátnosti, pak nastavíme vlastnost ProviderFlags pro tyto položky na pfHidden.
Poznámka: Vložení dalších položek k zabránění duplikace záznamů je také předpokladem používání dotazů na aplikačním serveru. Dotaz musí vložit další položky, aby záznamy se staly unikátními, když naše aplikace nepoužívá všechny položky.

Nastavování voleb ovlivňujících datové pakety
Vlastnost Options komponenty poskytovatele umožňují specifikovat zda BLOB nebo vnořené detailní tabulky jsou zasílány, zda jsou vloženy vlastnosti zobrazení položky, apod. Následující tabulka uvádí možné hodnoty, které mohou být vloženy do Options.
 
Hodnota Význam
poFetchBlobsOnDemand Hodnoty položek BLOB nejsou vkládány do datových paketů. Klientská aplikace musí požadovat tyto hodnoty, když je potřebuje. Pokud vlastnost FetchOnDemand klientské datové množiny je true, pak klient požaduje tyto hodnoty automaticky. Jinak, klientská datová množina použije metodu FetchBlobs klientské datové množiny k získání dat BLOB.
poFetchDetailsOnDemand Když poskytovatel reprezentuje Master vzájemného vztahu Master-detail, pak vnořené detailní hodnoty nejsou vloženy do datových paketů. Klientská aplikace musí požadovat tyto hodnoty, když je potřebuje. Pokud vlastnost FetchOnDemand klientské datové množiny je true, pak klient požaduje tyto hodnoty automaticky. Jinak, klientská datová množina použije metodu FetchDetails klientské datové množiny k získání vnořených detailů.
poIncFieldProps Datový paket obsahuje následující vlastnosti položek (jsou-li aplikovatelné): Alignment, DisplayLabel, DisplayWidth, Visible, DisplayFormat, EditFormat, MaxValue, MinValue, Currency, EditMask a DisplayValues.
poCascadeDeletes Když poskytovatel reprezentuje Master vzájemného vztahu Master-detail, pak detailní záznamy jsou rušený serverem automaticky pokud je zrušen záznam Master. K použití této volby, databázový server musí být nastaven k provádění kaskádovitého rušení jako součást referenční integrity.
poCascadeUpdates Když poskytovatel reprezentuje Master vzájemného vztahu Master-detail, pak detailní záznamy jsou aktualizovány serverem automaticky pokud je aktualizována odpovídající hodnota záznamu Master. K použití této volby, databázový server musí být nastaven k provádění kaskádovité aktualizace jako součást referenční integrity.
poReadOnly Klientská datová množina nemůže aplikovat aktualizace poskytovateli.

Přidávání přizpůsobených informací do datových paketů
Poskytovatel může zasílat aplikací definované informace do datových paketů pomocí události OnGetDataSetProperties. Tyto informace jsou kódované jako OleVariant a uloženy pod námi specifikovaným jménem. Klientské datové množiny v klientské aplikaci mohou pak získávat informace pomocí své metody GetOptionalParam. Můžeme také specifikovat, že informace budou vloženy do paketů Delta, které klientská datová množina zasílá při aktualizování záznamů. V tomto případě, klientská aplikace se nemusí starat o informace, ale server může zasílat okružní zprávy sám sobě.
Když přidáme přizpůsobené informace v události OnGetDataSetProperties, pak každý atribut (někdy nazývaný nepovinný parametr) je specifikován pomocí pole Variant, které obsahují tři prvky: jméno (řetězec), hodnota (Variant) a logický příznak indikující zda informace bude přidávána do paketů Delta, když klient aplikuje aktualizace. Více atributů může být přidáno vytvořením pole variant polí variant. Např. následující obsluha události OnGetDataSetProperties zasílá dvě hodnoty, čas poskytnutí dat a celkový počet záznamů ve zdrojové datové množině. Pouze informace o čase poskytnytí dat jsou vráceny když klient aplikuje aktualizace:
void __fastcallTMyDataModule1::Provider1GetDataSetProperties(TObject *Sender,
            TDataSet *DataSet, out OleVariant Properties)
{
  int ArrayBounds[2];
  ArrayBounds[0] = 0;
  ArrayBounds[1] = 1;
  Properties = VarArrayCreate(ArrayBounds, 1, varVariant);
  Variant values[3];
  values[0] = Variant("TimeProvided");
  values[1] = Variant(Now());
  values[2] = Variant(true);
  Properties[0] = VarArrayOf(values,2);
  values[0] = Variant("TableSize");
  values[1] = Variant(DataSet->RecordCount);
  values[2] = Variant(false);
  Properties[1] = VarArrayOf(values,2);
}
Když klient aplikuje aktualizace, pak čas poskytnutí původních záznamů může být přečten v události OnUpdateData poskytovatele:
void __fastcallTMyDataModule1::Provider1UpdateData(TObject *Sender,
                               TClientDataSet *DataSet)
{
  Variant WhenProvided = DataSet->GetOptionalParam("TimeProvided");
  ...
}

Reagování na datové požadavky klienta
Ve většině více vrstvových aplikací, klientské požadavky na data jsou zpracovány automaticky. Klientská datová množina požaduje datové pakety voláním GetRecords (prostřednictvím rozhraní IProvider nebo přizpůsobeného rozhraní). Poskytovatel reaguje automaticky předáním dat z přiřazené datové množiny, vytvořením datového paketu a zasláním paketu klientovi.
Poskytovatel má možnost editovat data po jejich sestavení do datového paketu, ale před odesláním paketu klientovi. Např. poskytovatel může zakódovat citlivá data před odesláním klientovi nebo z paketu odstranit záznamy na základě nějakého kritéria (jako je role uživatele v aplikacích MTS).
K editováni dat paketu před odesláním na klienta zapíšeme obsluhu události OnGetData. Datový paket je poskytnut jako parametr ve tvaru klientské datové množiny. Metody této klientské datové množiny použijeme k editaci dat před jejich odeslání klientovi.
Reagování na aktualizační požadavky klienta
Poskytovatel aplikuje aktualizace do záznamů databáze na základě datového paketu Delta získaného od klientské aplikace. Klient požaduje aktualizování voláním metody ApplyUpdates (prostřednictvím rozhraní IProvider nebo prostřednictvím přizpůsobeného rozhraní). Když poskytovatel získá aktualizační požadavek, je generována událost OnUpdateData, kde můžeme editovat Delta paket  a to dříve než je zapsán do datové množiny nebo ovlivňovat jak jsou aktualizace aplikovány. Po události OnUpdateData, poskytovatel použije svou přiřazenou komponentu řešitele k zápisu změn do databáze.
Komponenta řešitele provádí aktualizace záznam po záznamu. Dříve než řešitel aplikuje každý záznam, generuje na poskytovateli událost BeforeUpdateRecord, kterou můžeme použít k monitorování aktualizací před jejich aplikací. Když při aplikování záznamu vznikne chyba, pak řešitel volá obsluhu události OnUpdateError poskytovatele k řešení chyb. Chyby obvykle vznikají, protože změny porušují serverová omezení nebo když záznam databáze byl změněn jinou aplikací po jeho získání naší klientskou aplikací, ale před klientským požadavkem na aplikování aktualizací.
Chyby aktualizace mohou být zpracovány aplikačním serverem nebo klientem. Aplikační server zpracuje všechny chyby aktualizace, které k řešení nevyžadují interakci uživatele. Když aplikační server nemůže vyřešit chybovou podmínku, je dočasně uložena kopie ovlivňovaných záznamů. Po dokončení zpracování záznamů, aplikační server vrací počet vyskytnuvších se chyb klientské datové množině a kopie nevyřešených záznamů v paketu výsledkové množiny, který je předán zpět klientovi k budoucímu zpracování.
Poznámka: Komponenta uložené procedury nemůže být aktualizována tímto mechanismem. K aplikaci aktualizací na uloženou proceduru musíme provést jedno z: Obsluhy událostí pro všechny události poskytovatele přebírají množinu aktualizací jako klientská datová množina. Pokud obsluha událostí je určena pouze pro jisté typy aktualizací, pak můžeme datovou množinu filtrovat na základě stavu aktualizace záznamů a tak naše obsluha událostí nemusí procházet záznamy, které nepoužije. K tomuto, nastavíme vlastnost StatusFilter klientské datové množiny.
Editování Delta paketů před aktualizováním databáze
Dříve než poskytovatel aplikuje aktualizace na databázi, generuje událost OnUpdateData. Obsluha události OnUpdateData získá kopii paketu Delta jako parametr. Je to klientská datová množina.
V obsluze události OnUpdateData můžeme používat libovolné vlastnosti a metody klientské datové množiny k editaci paketu Delta před jeho zápisem do datové množiny. Nejužitečnější vlastností je UpdateStatus. UpdateStatus indikuje jaký typ modifikace současný záznam v paketu Delta reprezentuje. Mohou být použity hodnoty z následující tabulky:
 
Hodnota Popis
usUnmodified Obsah záznamu není změněn.
usModified Obsah záznamu má být změněn.
usInserted Záznam má být vložen.
usDeleted Záznam má být zrušen.

Např. následující obsluha události OnUpdateData vkládá současné datum do každého nového záznamu, který je vložen do databáze:
void __fastcallTMyDataModule1::Provider1UpdateData(TObject *Sender,
               TClientDataSet *DataSet)
{
  DataSet->First();
  while(!DataSet->Eof)
  {
    if (DataSet->UpdateStatus == usInserted)
    {
      DataSet->Edit();
      DataSet->FieldByName("DateCreated")->AsDateTime = Date();
      DataSet->Post();
    }
    DataSet->Next();
  }
}

Ovlivňování jak aktualizace jsou aplikovány
Událost OnUpdateData dává našemu poskytovateli možnost indikovat jak záznamy v paketu Delta jsou aplikovány do databáze. Implicitně, změny v paketu Delta jsou zapsány do databáze pomocí automaticky generovaného SQL příkazu UPDATE, INSERT nebo DELETE, jako:
UPDATE EMPLOYEES
  set EMPNO = 748, NAME = 'Smith', TITLE = 'Programmer 1', DEPT = 52
WHERE
  EMPNO = 748 and NAME = 'Smith' and TITLE = 'Programmer 1' and DEPT = 47
Pokud nespecifikujeme něco jiného, pak všechny položky v záznamech paketu Delta jsou vloženy do klauzule UPDATE a do klauzule WHERE. Nicméně můžeme chtít vyloučit některé tyto položky. Jednou z možností, jak to provést je nastavit vlastnost UpdateMode poskytovatele. UpdateMode můžeme přiřadit některou z těchto hodnot:
 
Hodnota Význam
upWhereAll Všechny položky jsou použity k lokalizaci (klauzule WHERE).
upWhereChanged Pouze klíčové položky a změněné položky jsou použity k lokalizaci záznamů.
upWhereOnly K lokalizaci záznamů jsou použity pouze klíčové položky.

Můžeme ale požadovat více řízení. Např. s předchozím příkazem, můžeme chtít zabránit položce EMPNO v modifikaci vyloučením z klauzule UPDATE a položky TITLE a DEPT vyloučit z klauzule WHERE k zabránění aktualizačním konfliktům, když ostatní aplikace modifikují data. Ke specifikaci klauzulí, kde se specifikované položky vyskytnou, použijeme vlastnost ProviderFlags. ProviderFlags může obsahovat libovolné hodnoty z následující tabulky:
 
Hodnota Popis
pfInWhere Položka neuváděná v klauzuli WHERE generovaných příkazů INSERT, DELETE a UPDATE.
pfInUpdate Položka neuváděná v klauzuli UPDATE generovaného příkazu UPDATE.
pfInKey Tato položka je použita v klauzuli WHERE generovaného příkazu SELECT, který je proveden při výskytu chyb aktualizace. Tento příkaz SELECT získá současné hodnoty modifikovaných nebo zrušených záznamů nebo záznamů způsobujících porušení klíče při vkládání.
pfHidden Položka je vložena do záznamu k zajištění unikátnosti, ale není viditelná nebo použitelná na klientské straně.

Tedy, následující obsluha události OnUpdateData vyloučí položku EMPNO z klauzule UPDATE a položky TITLE a DEPT z klauzule WHERE:
void __fastcallTMyDataModule1::Provider1UpdateData(TObject *Sender,
               TClientDataSet *DataSet)
{
  DataSet->FieldByName("EMPNO")->UpdateFlags.Clear();
  DataSet->FieldByName("EMPNO")->UpdateFlags << ufInUpdate;
  DataSet->FieldByName("TITLE")->UpdateFlags.Clear();
  DataSet->FieldByName("TITLE")->UpdateFlags << ufInWhere;
  DataSet->FieldByName("DEPT")->UpdateFlags.Clear();
  DataSet->FieldByName("DEPT")->UpdateFlags << ufInWhere;
}
Poznámka: Vlastnost UpdateFlags můžeme použít k ovlivnění jak aktualizace jsou aplikovány, když aktualizujeme datovou množinu a nepoužíváme dynamicky generované SQL. Tyto příznaky stále určují, které položky jsou použity k lokalizaci záznamů a které k zadávání aktualizací.

Monitorování individuálních aktualizací
Bezprostředně před aplikováním každé aktualizace, poskytovatel získá událost BeforeUpdateRecord. Tuto událost můžeme použít k editaci záznamů před jejich aplikováním a to podobně jako můžeme použít událost OnUpdateData k editaci celých Delta paketů. Např. poskytovatel neporovnává položky BLOB, když testuje konflikty aktualizace. Pokud chceme testovat konflikty aktualizace včetně položek BLOB, pak k tomu můžeme použít událost BeforeUpdateRecord.
Dále tuto událost můžeme použít k samotnému aplikování aktualizací nebo k zobrazení a odmítnutí aktualizací. Obsluha události BeforeUpdateRecord signalizuje řešiteli, že aktualizace již byla zpracována a tedy že nemá být aplikována. Řešitel pak tento záznam přeskočí, ale nezapočítává jej jako chybu aktualizace. Např. tato událost poskytuje mechanismus pro aplikování aktualizací pro uložené procedury (které nemohou být aktualizovány automaticky), umožněním poskytovateli přeskočit libovolný automatický proces na záznamu, při jeho aktualizování v obsluze události.
Řešení aktualizačních chyb na poskytovateli
Když chybová podmínka je porušena při odesílání záznamu v Delta paketu aplikačním serverem, pak vzniká událost OnUpdateError. Pokud aplikační server nemůže vyřešit chybu aktualizace, je dočasně uložena kopie ovlivňovaného záznamu. Po dokončení zpracování záznamů, aplikační server vrací počet vyskytnuvších se chyb klientské datové množině a kopie nevyřešených záznamů v paketu výsledkové množiny, jsou předány zpět klientovi pro jejich budoucí vyřešení.
Tento mechanismus umožňuje zpracovat libovolné chyby aktualizace, které nemohou být vyřešeny mechanicky na aplikačním serveru, a vyžadují pro vyřešení zásahy uživatele v klientské aplikaci.
Obsluha OnUpdateError získá kopii záznamu, který nemohl být změněn a chybový kód od databáze a indikaci zda řešitel se pokusil vložit, zrušit nebo aktualizovat záznam. Problémový záznam je předán zpět v datové množině. Na této datové množině nesmíme nikdy použit metody navigace dat. Můžeme ale, pro každou položku v datové množině použít vlastnosti NewValue, OldValue a CurValue k určení problému a provést nějakou modifikaci k vyřešení aktualizační chyby. Pokud obsluha události OnUpdateError může problém opravit, pak nastavíme parametr Response a tak opravený záznam je aplikován.
Reagování na události generované klientem
Komponenta poskytovatele implementuje obecnou událost, která umožňuje vytvářet své vlastní volání z klienta přímo poskytovateli. Je to událost OnDataRequest.
OnDataRequest nepatří do normální funkčnosti poskytovatele. Je to jednoduchá možnost umožňující našim klientům použít rozhraní IProvider k přímé komunikaci s poskytovateli na aplikačním serveru. Tato obsluha události přebírá OleVariant jako vstupní parametr a vrací OleVariant. Pomocí OleVariant, rozhraní je schopno předat libovolnou informaci na nebo z poskytovatele.
Ke generování události OnDataRequest, klientská aplikace volá metodu DataRequest rozhraní IProvider přímo. V beze stavových vzdálených datových modulech, přizpůsobené rozhraní na vzdáleném datovém modulu může volat metodu DataRequest objektu poskytovatele.
Zpracování serverových omezení
Většina systémů správy relačních databází implementuje omezení na svých tabulkách k zajištění integrity dat. Omezení je pravidlo, které vládne nad hodnotami v tabulkách a sloupcích nebo které ovládá vzájemné vztahy dat mezi sloupci v různých tabulkách. Např. většina relačních databází splňujících SQL-92 podporuje následující omezení: Poznámka: Tento seznam není výlučný. Náš databázový server může podporovat některá nebo všechna tato omezení a to částečně nebo úplně a může podporovat další omezení. Více informací o podporovaných omezeních zjistíme v dokumentaci našeho databázového serveru.
Omezení databázového serveru obvykle nahrazují mnoho typů testování dat, které aplikace tradičních relačních databází spravovaly v minulosti. Můžeme převzít výhody serverových omezení ve více vrstvových databázových aplikacích bez nutnosti duplikování omezení v kódu aplikačního serveru nebo klientské aplikace.
Vlastnost Constraints poskytovatele umožňuje replikovat a aplikovat serverová omezení na data předávaná na a získávaná z klientských aplikací. Když Constraints je true (implicitně), pak serverová omezení jsou replikována na klienty a ovlivňují klientské pokusy o aktualizaci dat.
Poznámka: Někdy nemusíme požadovat aplikování serverových omezení na data zasílaná klientskými aplikacemi. Např. klientská aplikace může získávat data v paketech a umožňovat lokální aktualizace záznamů před získáním dalších záznamů může požadovat zakázat některá serverová omezení, protože je používána nekompletní množina dat. K zabránění replikování omezení z aplikačního serveru na klientskou datovou množinu, nastavíme Constraints na false. Nezapomeňte také, že klientské datové množiny mohou zakazovat a povolovat omezení pomocí metod DisableConstraints a EnableConstraints.

Vytváření klientské aplikace

V mnoha ohledech, vytváření více vrstvové klientské aplikace se podobá vytváření tradičního dvouvrstvého klienta. Hlavní odchylky použité ve více vrstvovém klientovi jsou: K vytvoření více vrstvové klientské aplikace, začneme nový projekt a provedeme tyto kroky:
  1. Přidáme k projektu nový datový modul.
  2. Na datový modul umístíme komponentu připojení. Typ přidané komponenty připojení závisí na používaném komunikačním protokolu. Viz Struktura klientských aplikací.
  3. Nastavíme vlastnosti naší komponenty připojení na specifikaci aplikačního serveru, ke kterému chceme zřídit připojení. Více o nastavování komponent připojení se dozvíme v Připojování na aplikační server.
  4. Nastavíme další vlastnosti komponent připojení podle potřeby naší aplikace. Např. můžeme nastavit vlastnost ObjectBroker k umožnění komponentě připojení dynamicky volit z několika serverů.
  5. Umístíme potřebný počet komponent TClientDataSet do datového modulu a nastavíme vlastnost RemoteServer pro každou komponentu na jméno komponenty připojení umístěné v kroku 2.
  6. Nastavíme vlastnost ProviderName pro každou komponentu TClientDataSet. Pokud naše komponenta připojení je připojena na aplikační server při návrhu, pak můžeme zvolit dostupný aplikační server v rozbalovacím seznamu vlastnosti ProviderName. Při používání beze stavových vzdálených datových modulu je možno tento krok přeskočit.
  7. Vytvoříme klientskou aplikaci stejným způsobem jako vytváříme jiné databázové aplikace. Můžeme ale přidávat kód a nastavovat vlastnosti pro
Připojování na aplikační server
Pro zřízení a udržování připojení na aplikační server, klientská aplikace používá jednu nebo více komponent připojení. Tyto komponenty můžeme nalézt na stránce MIDAS Palety komponent.
Komponentu připojení použijeme k: Obvykle aplikační server je na jiném počítači než klientská aplikace, ale pokud server sídlí na stejném počítači jako klientská aplikace (např. v průběhu budování a testování celé více vrstvové aplikace), pak stále můžeme používat komponentu připojení k identifikaci aplikačního serveru jménem, specifikaci počítače serveru a použití rozhraní aplikačního serveru.

Specifikace připojení pomocí DCOM
Když pro komunikaci s aplikačním serverem používáme DCOM, pak klientská aplikace obsahuje komponentu TDCOMConnection pro připojování na aplikační server. TDCOMConnection používá vlastnost ComputerName k identifikaci počítače na kterém sídlí server.
Když ComputerName je prázdné, pak komponenta připojení DCOM předpokládá, že aplikační server sídlí na klientském počítači nebo že aplikační server má položku v systémových registrech. Pokud neposkytneme položky systémového registru pro aplikační server na klientu při používání DCOM a server sídlí na jiném počítači než server, pak musíme zadat ComputerName.
Poznámka: I když je položka systémového registru pro aplikační server, pak můžeme použít ComputerName k přepsání této položky. To je obzvláště užitečné pro vývoj, testování a ladění.
Pokud předáme jméno hostitelského počítače nebo serveru, který nemůže být nalezen, pak komponenta připojení DCOM generuje výjimku, když se pokusí otevřít připojení.
Pokud máme více serverů, mezi kterými naše klientská aplikace může volit, pak můžeme použít vlastnost ObjectBroker místo specifikování hodnoty pro ComputerName. Více informací viz Agentování připojení.

Specifikování připojení pomocí soketů
Připojení na aplikační server pomocí soketů můžeme zřídit na libovolném počítači, který má adresu TCP/IP. Tato metoda má výhodu, že je aplikovatelná na mnoha počítačích, ale nenabízí k použití žádný bezpečnostní protokol. Když používáme sokety, pak vložíme pro připojení na aplikační server komponentu TSocketConnection.
TSocketConnection identifikuje počítač serveru pomocí IP adresy nebo hostitelského jména systému serveru a číslem portu programu vyřízujícího sokety (Scktsrvr.exe nebo Scktsrvc.exe), který je spuštěn na počítači serveru.
Adresu IP a číslo portu specifikují tyto vlastnosti TSocketConnection:

Address a Host se vzájemně vylučují. Nastavení jedné zruší hodnotu druhé.
Pokud máme více serverů, ze kterých naše klientská aplikace může volit, pak místo nastavování hodnot vlastnosti Address nebo Host, můžeme použít vlastnost ObjectBroker. Více informací viz Agentování připojení.
Implicitně, hodnota Port je 211, což je implicitní číslo portu programu vyřizujícího sokety dodaného s C++ Builderem. Pokud vyřizovač soketů je konfigurován na použití jiného portu, pak nastavíme Port na tuto hodnotu.
Poznámka: Konfigurovat port Vyřizovače soketu za běhu můžeme kliknutím pravým tlačítkem myši na jeho ikoně.

Specifikování připojení pomocí OLEnterprise
Když pro komunikaci s aplikačním serverem používáme OLEnterprise, pak klientská aplikace musí vložit pro připojení na aplikační server komponentu TOLEnterproseConnection. Když používáme OLEnterprise, pak se můžeme připojovat na počítač serveru přímo nebo můžeme použít Business Object Broker.
K použití OLEnterprise bez Business Object Broker, nastavíme vlastnost ComputerName na jméno počítače serveru a to stejně jako používáme vlastnost ComputerName pro připojení DCOM. K použití Business Object Broker, nastavíme vlastnost BrokerName na jméno Business Object Broker.
ComuterName a BrokerName se vzájemně vylučují. Nastavení hodnoty jedné vlastnosti ruší hodnotu druhé.

Agentování připojení
Pokud máme více serverů, ze kterých klientská aplikace může volit, pak můžeme použít Object Broker k lokalizaci dostupného serverového systému. Objekt agenta udržuje seznam serverů ze kterých komponenta připojení může volit. Když se komponenta připojení potřebuje připojit k aplikačnímu serveru, pak se ptá Objektu agenta na jméno počítače (nebo IP adresu případně jméno hostitele). Agent předává jméno počítače a komponenta připojení formuje připojení. Pokud předané jméno nepracuje (např. server je zastaven), pak Agent předá jiné jméno atd. dokud připojení není navázáno.
Po zformování připojení připojovací komponentou s jménem předaným Agentem, je jméno uloženo jako hodnota odpovídající vlastnosti (ComputerName, Address nebo Host). Pokud připojovací komponenta později připojení uzavře, pak při pokusu o opětovné otevření připojení se použijí tyto uložené hodnoty a pouze při neúspěchu připojení je Agent dotazován na nové jméno.
Objekt agenta použijeme specifikováním vlastnosti ObjectBroker naší připojovací komponenty. Když vlastnost ObjectBroker je nastavena, pak připojovací komponenta neukládá hodnoty ComputerName, Address nebo Host.
Poznámka: Vlastnost ObjectBroker nepoužíváme s připojením OLEnterprise. OLEnterprise má své vlastní agentovací služby.

Spravování serverových připojení
Hlavním významem připojovacích komponent je lokalizovat a připojit se k aplikačnímu serveru. Protože spravují serverové připojení, můžeme také použít komponentu připojení k volání metod rozhraní aplikačního serveru.
Následující body popisují jak používat připojovací komponentu pro: Připojování na server
K lokalizaci a připojení na databázový server, musíme nejprve nastavit vlastnosti komponenty připojení k identifikaci aplikačního serveru. Tento proces je popsán v Připojování na aplikační server. Dále před otevřením připojení, libovolné klientské datové množiny, které používají připojovací komponentu, k získání rozhraní IProvider, musí to indikovat nastavením jejich vlastností RemoteServer ke specifikování připojovací komponenty. Klientské datové množiny pak nastaví jejich vlastnosti ProviderName před otevřením připojení a tak když připojení je otevřeno, můžeme získat příslušné rozhraní IProvider.
Připojení je otevřeno automaticky, když klientská datová množina se pokusí zpřístupnit rozhraní IProvider. Např. nastavením vlastnosti Active klientské datové množiny na true otevřeme připojení.
Pokud nepřipojíme klientskou datovou množinu na připojovací komponentu aby mohla používat rozhraní IProvider, pak můžeme otevřít připojení nastavením vlastnosti Connected komponenty připojení na true.
Před zřízením připojení připojovací komponenty na aplikační server, je generována událost BeforeConnect. Můžeme provést nějaké potřebné speciální akce před připojením v kódu obsluhy událostí BeforeConnect. Po zřízení připojení, připojovací komponenta generuje událost AfterConnect pro další speciální akce.

Rušení nebo změna serverového připojení
Komponenta připojení zruší připojení na aplikační server když:

Poznámka: Místo používání jedné připojovací komponenty k přepínání mezi dostupnými aplikačními servery, klientská aplikace může mít více připojovacích komponent, kde každá z nich je připojena na jiný aplikační server.
Dříve než připojovací komponenta ukončí připojení, je automaticky volána obsluha události BeforeDisconnect, pokud je poskytnuta. Pokud potřebujeme provést nějakou speciální akci před odpojením, pak ji zapíšeme do obsluhy BeforeDisconnect. Podobně, po ukončení připojení je volána obsluha události AfterDisconnect. Pokud potřebujeme provést nějakou speciální akci po ukončení připojení, pak je musíme zapsat zde.

Volání rozhraní serveru
Aplikace nepotřebuje volat rozhraní IProvider přímo, protože příslušná volání jsou provedena automaticky, když používáme vlastnosti a metody klientské datové množiny. Jedinou podstatnou výjimkou je přímé volání metody DataRequest poskytovatele na aplikačním serveru. Více informací o používání DataRequest nalezneme v Reagování na klientem generované události. Když potřebujeme volat rozhraní poskytovatele, pak můžeme použít vlastnost Provider klientské datové množiny, která reprezentuje data od poskytovatele.
I když klientská aplikace nepotřebuje volat rozhraní IDataBroker aplikačního serveru, může přidávat své vlastní rozšíření k rozhraní aplikačního serveru. Když rozšíříme rozhraní aplikačního serveru, pak potřebujeme nalézt způsob volání tohoto rozšíření pomocí připojení vytvořeného naší komponentou připojení. Můžeme to provést pomocí vlastnosti AppServer připojovací komponenty. AppServer je Variant, který reprezentuje rozhraní aplikačního serveru. K volání tohoto rozhraní, musíme vyřizující rozhraní získat z této Variant. Toto vyřizující rozhraní má stejné jméno jako rozhraní vytvořené při vytváření vzdáleného datového modulu, ale má přidaný řetězec Disp. Tedy pokud náš vzdálený datový modul se nazývá MyAppServer, pak můžeme použít AppServer k volání svého rozhraní takto:
IMyAppServerDisp TempInterface(LPDISPATCH(MyConnection->AppServer));
TempInterface->SpecialMethod(x,y);

Zpracování omezení
Omezení databázového serveru a implicitní výrazy mohou být importovány do Datového slovníku pomocí průzkumníka SQL. Omezení a implicitní výrazy v Datovém slovníku jsou automaticky dostupné pro datové množiny podporující BDE v aplikačním serveru. Implicitně, serverová omezení a implicitní výrazy jsou předávány klientským datovým množinám aplikačním serverem, a můžeme je potom využívat při editaci dat uživatelem. Když omezení jsou v činnosti, pak editace dat v klientské aplikaci, které nesplňují serverová omezení jsou zachycena na klientské straně, a nejsou předávána na aplikační server. Tím je snížen počet chyb generovaných v průběhu aktualizačního procesu.
Během importování serverových omezení a výrazů je nejdůležitější službou chránit integritu dat mezi platformami a aplikacemi a mohou být okamžiky, kdy vývojář potřebuje dočasně zakázat omezení. Např. pokud serverové omezení je založené na současné maximální hodnotě v položce, pak na klientu se může tato hodnota lišit od hodnoty na databázovém serveru a omezení mohou pracovat různě. V jiném případě, pokud klientská aplikace aplikuje na záznamy filtr při povoleném omezení, pak filtr může interferovat nějakým způsobem s podmínkou omezení. Ve všech těchto případech aplikace může zakázat testování omezení.
K dočasnému zákazu omezení voláme metodu DisableConstraints klientské datové množiny. Při každém volání DisableConstraints je inkrementován čítač odkazů. Pokud hodnota tohoto čítače je větší než nula, pak omezení nejsou vnucována klientské datové množině.
K obnovení omezení pro klientskou datovou množinu, voláme metodu EnableConstraints. Každé volání EnableConstraints dekrementuje čítač odkazů. Když čítač odkazů je nula, pak omezení jsou opět povolena.
Tip: Volání DisableConstraints a EnableConstraints tvoří pár k zajištění, že omezení jsou povolena, když chceme aby byla.
Aktualizování záznamů
Když klientská aplikace je připojena na aplikační server, pak klientské datové množiny pracují s lokální kopií dat předaných z aplikačního serveru. Uživatel vidí a edituje tuto kopii v datových ovladačích klientské aplikace. Pokud serverová omezení jsou povolena na klientské datové množině, pak jsou stejně omezena editace uživatele. Uživatelské změny jsou dočasně uloženy klientskou datovou množinou v interně udržovaném deníku změn. Obsah deníku změn je ukládán jako datový paket ve vlastnosti Delta. K udělání změn v Delta trvalými, klientská datová množina je musí aplikovat do databáze.
Když klient aplikuje aktualizace na server pomocí rozhraní IProveder, pak proběhnou následující kroky:
  1. Klientská aplikace volá metodu ApplyUpdates objektu klientské datové množiny. Tato metoda předává obsah vlastnosti Delta klientské datové množiny na aplikační server prostřednictvím rozhraní IProvider současně přiřazeného ke klientské datové množině. Delta je datový paket, který obsahuje aktualizace, vkládání a rušení záznamů v klientské datové množině.
  2. Komponenta poskytovatele aplikačního serveru aplikuje aktualizace do databáze a odkládá všechny problémové záznamy, které nelze vyřešit na úrovni serveru. Viz Řešení aktualizačních konfliktů při aplikování aktualizací serverem.
  3. Komponenta poskytovatele aplikačního serveru vrací všechny nevyřešené záznamy na klienta v datovém paketu Result. Datový paket Result obsahuje všechny záznamy, které nemohly být aplikovány. Také obsahuje chybové informace, jako jsou chybové zprávy a chybové kódy.
  4. Klientská aplikace se pokusí vyřešit chyby aktualizací vrácených v datovém paketu Result záznam po záznamu.
Poznámka:  Pokud používáme transakce MTS nebo aktivaci just-in-time, pak nemůžeme použít rozhraní IProvider k aplikování aktualizací. Tento proces musíme provést pomocí rozhraní aplikačního serveru. Více informací naleznete v Podporování beze stavových vzdálených datových modulů.

Aplikování aktualizací
Změny provedené na lokální kopii dat klientské datové množiny nejsou zasílány na aplikační server dokud klientská aplikace nezavolá pro datovou množinu metodu ApplyUpdates. ApplyUpdates přebírá jeden parametr, MaxErrors, určující maximální počet chyb, které aplikační server bude tolerovat před zrušením aktualizačního procesu. ApplyUpdates vrací skutečný počet vzniklých chyb, který je vždy menší nebo roven MaxErrors+1. Tato hodnota je nastavena k indikaci počtu záznamů, které nebyly zapsány do databáze. Aplikační server také vrací tyto záznamy na klientskou datovou množinu v datové množině.
Klientská datová množina je zodpovědná za vyřešení konfliktů pro záznamy, které generují chyby. ApplyUpdates aktuálně volá metodu Reconcile klienské datové množiny k zaslání aktualizací na aplikační server a Reconcile vyvolá obsluhu události OnReconcileError klientské datové množiny (pokud existuje), vždy pro každý záznam, který generoval chybu na serveru.

Řešení aktualizačních konfliktů
Poskytovatel na aplikačním serveru vrací chybné záznamy a chybové informace na klientskou datovou množinu v datovém paketu Result. Pokud aplikační server vrátí počet chyb větší než 0, pak pro každý záznam v datovém paketu Result vzniká událost OnReconcileErrors klientské datové množiny.
Pokud nechceme pouze ignorovat záznamy vrácené aplikačním serverem, pak musíme poskytnout kód obsluze události OnReconcileError. Obsluha události OnReconcileError má čtyři parametry:

Následující kód ukazuje obsluhu události OnReconcileError, která používá dialogové okno řešení chyb z jednotky RecError, kterou najdeme v adresáři zásobníku objektů (k použití tohoto dialogu vložíme hlavičkový soubor RecError.hpp do kódu naší jednotky).
void __fastcall TForm1::ClientDataSetReconcileError(TClientDataSet *DataSet,
      EReconcileError *E, TUpdateKind UpdateKind, TReconcileAction &Action)
{
  Action = HandleReconcileError(DataSet, UpdateKind, E);
}
Obnovování záznamů
Klientská aplikace pracuje s kopií dat z aplikačního serveru. V průběhu času ostatní uživatelé mohou modifikovat tato data a tak naše klientská aplikace má již zastaralou kopii dat. Stejně jako jiné datové množiny i klientská datová množina má metodu Refresh, která aktualizuje své hodnoty na současné hodnoty na serveru. Volání Refresh pracuje pouze, když deník změn je prázdný. Volání Refresh při neaplikovaných aktualizacích generuje výjimku.
Klientská aplikace může také aktualizovat data při nedotčení deníku změn. Provedeme to voláním metody RefreshRecord klientské datové množiny. Na rozdíl od metody Refresh, metoda RefreshRecord aktualizuje pouze současný záznam v datové množině. RefreshRecord změní hodnoty záznamu původně získané z aplikačního serveru, ale ztratí všechny změny v deníku změn.
Varování: Ne vždy je vhodné volat RefreshRecord. Při vzniku konfliktu se změnami provedenými jinými uživateli v připojené datové množině, volání RefreshRecord tento konflikt zamaskuje. Když klientská aplikace aplikuje své aktualizace, pak žádný konflikt nevzniká a aplikace jej nemusí řešit.
K zabránění maskování aktualizačních chyb, klientská aplikace může testovat, zda jsou nevyřízené aktualizace před voláním RefreshRecord. Např. následující kód generuje výjimku, pokud se pokusíme obnovit modifikovaný záznam:
if (ClientDataSet1->UpdateStatus != usUnModified)
  throw Exception
    ("You must apply updates before refreshing the current record.");
ClientDataSet1->RefreshRecord;
Získávání parametrů z aplikačního serveru
Jsou dvě situace, kdy klientská aplikace potřebuje získat hodnoty parametrů z aplikačního serveru: Klient požaduje hodnotu parametrů z aplikačního serveru voláním metody FetchParams. Parametry jsou vráceny v datových paketech z aplikačního serveru a přiřazeny vlastnosti Params klientské datové množiny.
Při návrhu, vlastnost Params můžeme inicializovat volbou Fetch Params v místní nabídce klientské datové množiny.
Poznámka: Metoda FetchParams (nebo volba Fetch Params) pracuje pouze tehdy, pokud klientská datová množina je připojena k poskytovateli, který umí předávat parametry. TProvider může předávat parametry, pokud reprezentuje TQuery nebo TStoredProc.
Vlastnost Params může být také použita k zasílání hodnot parametrů na aplikační server. Tím jsme se ale již zabývali v minulé kapitole.

Přizpůsobování aplikačního serveru

Architektura MIDAS je značně flexibilní a tak můžeme přizpůsobit aplikační server k zajištění specifických potřeb naší aplikace. Např. můžeme:
Rozšiřování rozhraní aplikačního serveru
Klientská aplikace spolupracuje s aplikačním serverem implementací třídy vytvořené Průvodcem vzdáleným datovým modelem nebo Průvodcem datovým modelem MTS. Používá své rozhraní jako základ všech komunikací s aplikačním serverem. Jediná výjimka z tohoto pravidla je, když klientská datová množina se dotazuje přímo komponenty poskytovatele pomocí rozhraní IProvider.
Když používáme transakce nebo aktivizaci just-in-time pod MTS, pak je obzvláště důležité, aby všechna komunikace s aplikačním serverem probíhala prostřednictvím implementované třídy rozhraní. Libovolná jiná komunikace obcházející proxy MTS, může způsobit chyby.
Můžeme k naší implementaci třídy rozhraní přidávat další funkce k poskytnutí další podpory pro naše klientské aplikace. Toto rozhraní je potomkem IDataBroker a je vytvořeno automaticky Průvodcem při vytváření vzdáleného datového modulu. Pro přidání k implementaci třídy rozhraní použijeme Editor knihovny typů.
Když přidáváme k rozhraní COM, pak naše změny jsou přidávány k naší jednotce zdrojového kódu a souboru knihovny typů (TLB).
Poznámka: Soubor TLB není uložen, dokud ji neuložíme z Editoru knihovny typů nebo v IDE nezvolíme File | Save All.
Když již máme přidány k naši implementaci třídy rozhraní, umístíme vlastnosti a metody které jsme přidávali k naši implementaci třídy. Kod přidáme na konec této implementace.
Klientská aplikace volá rozšíření našeho rozhraní pomocí vlastnosti AppServer své připojovací komponenty. Více informací nalezneme ve Volání rozhraní serveru.
Poskytování z a řešení na datové množině
Komponenta poskytovatele získává svá data od datové množiny specifikované vlastností DataSet. Implicitně, ale když komponenta TProvider aplikuje aktualizace a řeší aktualizační chyby, pak komunikuje přímo s databázovým serverem pomocí dynamicky generovaných příkazů SQL. Tato možnost má výhodu v tom, že naše serverová aplikace nemusí slučovat aktualizace dvakrát (poprvé na datovou množinu a pak na vzdálený server). Nicméně, když naše komponenta poskytovatele aplikuje aktualizace a řeší problémy pomocí SQL, pak vlastnost DataSet musí specifikovat datovou množinu podporující BDE.
Můžeme použít komponentu poskytovatele, která aplikuje aktualizace a řeší chyby přímo na datové množině aplikačního serveru. Pomocí této možnosti můžeme použít klientskou datovou množinu nebo přizpůsobenou datovou množinu na našem aplikačním serveru. Tím můžeme reprezentovat data, která nemohou být zpřístupněna žádným ovladačem BDE. K řešení na datové množině, která nepodporuje BDE použijeme komponentu TDataSetProvider. Můžeme také řešit na datovou množinu podporující BDE místo dynamicky generovaných příkazů SQL nastavením vlastnosti ResolveToDataSet naší komponenty TProvider na true.
Poznámka: Na rozdíl od TProvider, TDataSetProvider nezávisí na BDE. Když použijeme tuto komponentu, pak naše serverová aplikace nemusí obsahovat BDE. To může zjednodušit šíření.

Správa transakcí ve více vrstvových aplikacích

Když klientská aplikace aplikuje aktualizace na aplikační server, pak komponenta poskytovatele automatizuje proces aplikování aktualizací a řešení konfliktů v transakci. Tato transakce je zapsána, pokud počet problémových záznamů nepřekračuje počet MaxErrors specifikovaný jako parametr metody ApplyUpdates. Jinak je transakce zrušena.
Dále můžeme přidat podporu transakcí k naší serverové aplikaci přidáním komponenty databáze nebo pomocí průchozího SQL. Pracuje to stejným způsobem jako používáme pro správu transakcí ve dvou vrstvových aplikacích. S problematikou řízení transakcí jsme se již seznámili.
Pokud používáme MTS, pak můžeme rozšířit naši podporu transakcí na MTS transakce. MTS transakce mohou zahrnovat libovolnou logiku na našem aplikačním serveru. Dále, protože také podporuje dvoufázový commit, MTS transakce se mohou týkat více databází.
Varování: Dvoufázový commit je plně podporován pouze na Oracle 7 a MS-SQL databázích. Jestliže naše transakce se týká více databází, a některé z nich jsou jiné než Oracle 7 nebo MS-SQL, pak naše spuštěná transakce může riskovat pouze částečný úspěch. V libovolné jedné databázi, nicméně, vždy máme podporu transakcí.
K použití MTS transakcí, rozšíříme rozhraní aplikačního serveru k vložení metod jejich volání zaobalují transakci. Když konfigurujeme vzdálený datový modul MTS, pak zadáme, že musíme pracovat v transakcích. Když klient volá metodu rozhraní našeho aplikačního serveru, pak je automaticky vložena do transakce. Všechna klientská volání našeho aplikačního serveru jsou tedy vkládány do transakce dokud neurčíme, že transakce je kompletní. Tato volání mohou být všechna úspěšná nebo jsou zrušena.
Poznámka: Nesmíme kombinovat transakce MTS s explicitními transakcemi vytvořenými komponentou databáze nebo pomocí průchozího SQL.

Podporování vzájemného vztahu Master-detail

Mezi klientskými datovými množinami v naší klientské aplikaci můžeme vytvořit vzájemný vztah Master-detail a to stejným způsobem jako v jedno nebo dvou vrstvové aplikaci. Tato možnost má ale dva hlavní nedostatky: Ve více vrstvových aplikacích můžeme zabránit těmto problémům použitím vnořených tabulek k reprezentaci vzájemného vztahu Master-detail. Provedeme to tak, že nastavíme vzájemný vztah Master-detail mezi tabulkami na aplikačním serveru. Pak nastavíme vlastnost DataSet naší komponenty poskytovatele na tabulku Master. Když klient volá metodu GetRecord poskytovatele, pak je automaticky vložena detailní datová množina jako položka DataSet do záznamu datového paketu. Když klient volá ApplyUpdates poskytovatele, pak aplikování aktualizací proběhne správně.

Podporování beze stavových vzdálených datových modulů

Když používáme transakce a aktivaci just-in-time pro MTS, pak nemůžeme používat rozhraní IProveder. Je to z důvodu, že: Můžeme stále používat poskytovatele na aplikačním serveru. Abychom to mohli provést, musíme zapsat své vlastní beze stavové rozhraní. Pokud potřebujeme vložit stavovou informaci, pak musíme přidat parametr k volání rozhraní nebo vložíme stavovou informaci do našich datových paketů jako přizpůsobenou informaci.
Poznámka: Pod MTS, každá metoda našeho rozhraní musí volat metodu SetComplete objektu IObjectContext k oznámení dokončení. To slouží k dokončení transakce a aplikační server může být deaktivován.
Pro získávání záznamů od poskytovatele, rozšíříme rozhraní aplikačního serveru, k vložení volání k získání záznamů od specifického poskytovatele na aplikačním serveru. Tato metoda pracuje nějak jako následující metoda implementující třídy MTS:
OleVariant__fastcallTMyRemoteDataModuleImpl::GetCustomerRecords
       (bool MetaData, int &RecsOut)
{
  OleVariant Result = NULL;
  try
  {
    if (MetaData)
      Result = CustomerProvider->GetRecords(0, RecsOut);
    else
      Result = CustomerProvider->GetRecords(-1, RecsOut);
  }
  catch (...)
  {
    ObjectContext.SetAbort();
    return Result;
  }
  ObjectContext.SetComplete();
  return Result;
}
Na klientské straně, můžeme přiřadit vrácenou hodnotu touto metodou přímo vlastnosti Data klientské datové množině:
ClientDataSet1->Data =
    MyConnectionComponent->AppServer.GetCustomerRecords(False, RecsOut);
Pro aplikování aktualizací, přidáme metodu k rozhraní aplikačního serveru takto:
OleVariant__fastcallTMyRemoteDataModuleImpl::ApplyCustomerUpdates
     (OleVariant Delta, int MaxErrors, int &ErrorCount)
{
  OleVariant Result = NULL;
  try
  {
    OleVariant Result =
        CustomerProvider->ApplyUpdates(Delta, MaxErrors, ErrorCount);
  }
  catch (...)
  {
    ObjectContext.SetAbort();
    return Result;
  }
  ObjectContext.SetComplete();
  return Result;
}
Na straně klienta, místo volání metody ApplyUpdates klientské datové množiny, musíme volat tuto metodu rozhraní:
ClientDataSet1->CheckBrowseMode();
if (ClientDataSet1->ChangeCount > 0)
{
  IMyRemotedataModuleDisp TempInterface(LPDISPATCH(MyConnection->AppServer));
  ClientDataSet1->Reconcile(
      TempInterface->ApplyCustomerUpdates(ClientDataSet1->Delta,
                     ClientDataSet1->MaxErrors, ErrCount);
}

Distribuovatelné klientské aplikace jako ovladače ActiveX

Architektura distribuovaných databází C++ Builderu může být kombinovaná se službami ActiveX k distribuování klientských aplikací jako ovladačů ActiveX.
Když distribuujeme naší klientskou aplikaci jako ActiveX, pak vytvoříme aplikační server jako pro libovolnou jinou více vrstvovou aplikaci. Jediné omezení je to, že jako komunikační protokol musíme používat DCOM nebo sokety, protože nemůžeme počítat s tím, že na klientských počítačích je instalováno běhové prostředí OLEnterprise.
Když vytváříme klientskou aplikaci, pak musíme použít jako její základ Active Form místo normálního formuláře. Viz Vytváření Active Form pro klientskou aplikaci.
Když již máme vytvořenou a šíříme klientskou aplikaci, pak ji můžeme zpřístupnit z Webovského prohlížeče podporujícího ActiveX a jiném počítači. Abychom z Webovského prohlížeče mohli úspěšně získat klientskou aplikaci, Webovský server musí být spuštěn na počítači, který má klientskou aplikaci.
Pokud klientská aplikace používá pro komunikaci klientské aplikace a aplikačního serveru DCOM, pak počítač s Webovským prohlížečem musí umožňovat práci s DCOM.
Vytváření Active Form pro klientskou aplikaci
  1. Protože klientská aplikace bude šířena jako ovladač ActiveX, musíme mít Webovský server spuštěn na stejném počítači jako klientskou aplikaci. Musíme používat server typu Netscape server nebo IIS Microsoft, nebo můžeme zapsat svůj vlastní Webovský server používající komponenty soketů.
  2. Vytvoříme klientskou aplikaci obdobně jako libovolnou jinou klientskou aplikaci, pouze začneme volbou File | New | Active Form místo normálního zahájení projektu.
  3. Pokud naše klientská aplikace používá datový modul, přidáme volání k explicitně vytvořenému datovému modelu v inicializaci aktivního formuláře.
  4. Když naši klientskou aplikaci dokončíme, přeložíme projet a zvolíme Project | Web Deployment Options. V zobrazeném dialogovém okně musíme:
  5. Na konec, vybereme Project | WebDeploy k šíření klientské aplikace jako aktivního formuláře.
Libovolný Webovský prohlížeč, který může spustit aktivní formulář, může spustit naší klientskou aplikaci specifikací souboru HTML vytvořeným při šíření klientské aplikace. Tento HTML soubor má stejné jméno jako projekt naší klientské aplikace a je umístěn v adresáři specifikovaném jako cílový adresář.
 
20. Vytváření více vrstvových aplikací