Aplikacje serwera i klienta DCOM, które zamierzamy stworzyć są
Transkrypt
Aplikacje serwera i klienta DCOM, które zamierzamy stworzyć są
DCOM Aplikacje serwera i klienta DCOM, które zamierzamy stworzyć są podobne do tych zrobionych w ćwiczeniu dotyczącym TCP/IP. Aplikacja serwera będzie jedno wątkowa, a co za tym idzie będzie mogła obsłużyć jednego klienta jednocześnie. Serwer TCP/IP pozwalał na kilka jednoczesnych połączeń klientów i używał jednego połączenia z bazą danych by wygenerować pakiet danych. Klienci serwera DCOM będą również dzielili między sobą pojedyncze połączenie z bazą. 1. Wybierz File | New Application. Pojawi się nowa aplikacja w Delphi. 2. Wybierz Choose File | New… | Multi-tier | Remote Data Module i kreator Remote Data Module Wizard pojawi się na ekranie. Wpisz Class Name w okno dialogowe jak pokazano poniżej i przyciśnij przycisk OK. 3. Zapisz wszystkie pliki do katalogu który wybrałeś pod nazwami: Unit1.pas (Form1), Unit2.pas (MyServer) i DCOMServer.dpr (DCOMServer). 4. Upuść komponent TDatabase na MyServer i ustaw jego właściwości w ten sam sposób jak zrobiliśmy to w aplikacji przykładowej Hello World. Ustaw właściwość Database1.HandleShared na True. 5. Upuść TQuery na MyServer i skojaż ten komponent z Database1. Ustaw jej właściwość SQL na SELECT * FROM department’. 6. Upuść komponent Tprovider na MyServer i ustaw jego właściwość DataSet na Query1. 7. Kliknij na MyServer i wybierz komendę Edit | Add to interface. 8. W dialogu Add to interface wpisz deklaracje metody GetDepartments Ta metoda będzie robiła to samo co zamieszczona w aplikacji przykładowej TCP/IP – doręczała pakiet danych od Proiver1 w aplikacji serwera do ClientDataSet1 w aplikacji klienta. Wciśnij przycisk OK, gdy skończysz pisać tą deklaracje. W tle środowisko Delphi stworzyło czwarty plik, DCOMServer.tlb i dodało go do projektu. Jest to binarna biblioteka która zawiera definicje co nasz serwer udostępnia innym aplikacją. Deklaracja metody GetDepartments została napisana jako biblioteka powiązana z interfejsem ‘IMyServer’. Nazwa interfejsu jest bardzo podobna do nazwy naszego remote data module. To nie przypadek. Implementacja jako pusta metoda została dodana do kodu TmyServer w Unit2. Delphi domyślił się, że klasa TMyServer implementuje interfejs IMyServer. Gdy klient pobiera referencje do interfejsu IMyServer oraz wywołuje GetDepartments, wtedy metoda TMyServer.GetDepartments zostanie wykonana i zwrócony zostanie pakiet danych do pamięci aplikacji klienta. 9. Wybierz View | Type Library, rozwiń ImyServer w drzewie po lewej Type Library Editor kliknij ImyServer, a następnie na przycisk New Method Metod pasku narzędziowym edytora. Zmień nazwe nowej metody na ApplyDepartmentUpdates i wybierz zakładkę Parameters po prawej stronie okienka edytora. Wypełnij parametry wartościami jak na poniższym rysunku. 10. Wybierz File | Save all. Nowy unit DCOMServer_TLB.pas zostanie dodany do projektu. Zawiera on deklaracje Pascal-a, opisujące binarną zawartość biblioteki typów. Gdy masz troszkę czasu możesz w tym pliku znaleźć również deklaracje IMyServer i IMyServerDisp. Każdy interfejs musi być zaimplementowany w jednej lub wielu coclass. Jedna coclass może implementować kilka interfejsów DCOM. W naszym przypadku TmyServer jest implementacją coclass. Delphi generuje DCOMServer_TLB.pas za każdym razem ja zmieni się zawartość biblioteki typów. Nigdy nie należy próbować modyfikować tego pliku, ponieważ wpisany kod może być zmieniony bez ostrzeżenia. Ten plik może być użyty w innych aplikacjach by umożliwić dostęp do funkcji udostępnianych na serwerze. Implementacja w bibliotece typów interfejsów TmyServer w Unit2 wiąże ten plik w jego sekcji interface. Oto część kodu z pliku biblioteki typów deklarująca interfejs IMyServer. Poniżej jest implementacja sekcji Unit2 utworzonej w środowisku Delhi. Dwie metody naszego interfejsu wyglądają tak jak zwykle metody klasy. Na końcu pliku jest konstrukcja, która tworzy fabrykę komponentów dla implementacji coclass. Ten kod rozszerza możliwości serwera do komunikacji z nim z zewnątrz Ostatnim krokiem jest uzupełnienie dwóch pustych metod implementujących interfejs. Odległy moduł danych MyServer może wyglądać podobnie do poniższego. Dodajmy poniższy kod do Unit2: Całkiem proste. Podczas budowy komponenty wizualne wygenerowały za nas większość kodu bez większej iteracji z naszej strony. Po prostu zadeklarowaliśmy kilka metod. W ten sposób można skoncentrować się na logice biznesowej naszej aplikacji. Czy pisaliśmy kod komunikacji? Nie, bo DCOM robi to przeźroczystym dla aplikacji. Uruchom Aplikacje a wtedy class factory stworzone na końcu Unit2 zapisze referencje do DCOMServer.MyServer w rejestrze Windows by serwer był widoczny dla innych aplikacji. Aplikacja klienta będzie podobna do tej która stworzyliśmy w przykładzie TCP/IP. 1. Wybierz File | New Application. Pojawi się nowa pusta aplikacja. 2. Wybierz File | New… | Data Module i do aplikacji zostanie dodany nowy moduł danych. 3. Zapisz wszystkie pliki do wybranego przez ciebie katalogu pod nazwami Unit1.pas (Form1), Unit2.pas (DataModule2) i Project1.dpr (Project1). 4. Upuść komponent TclientDataSet na DataModule2. 5. Umieść komponent TdataSource na DataModule2 i ustaw jego własność DataSet na ClientDataSet. 6. Dodaj referencje do biblioteki typów serwera wybierając Project | Add to project i znajdując DCOMServer_TLB.pas w katalogu serwera. 7. Dodaj DCOMServer_TLB do listy unitów w clauzuli uses sekcji interface unitu Unit2. 8. Stwórz właśniwości DataModule2 jak pokazano poniżej. 9. Upuść komponent TactionList na DataModule1. Podwójne klikniecie na ActionList1 da nam Action List Editor. Stwórzmy 2 nwe akcje o nazwach Action1i Action2 nadanych domyślnie ustaw ich własność Caption odpowiednio na ‘&Apply’ i ‘&Cancel’ . 10. Wybierz Action1 i kliknij na zakładkę Events Object Inspektor, następnie twórz obsługę zdarzeń OnExecute i OnUpdate, jak pokazano poniżej. 11. Stwórz obsługę zdarzenia OnExecute Action2 by odwołać zmiany w danych i przypisz do obsługi jego zdarzenia OnUpdate metodę Action1Update. 12. Stwórz trzecią akcję o nazwie Action3. Ustaw właściwość Caption na ‘Refresh’ i określ obsługę zdarzeń OnUpdate and OnExecute 13. Ustaw Unit2 jako główna formę naszej aplikacji klienta. 14. Upuść komponent TDBGrid, TDBNavigator i trzy komponenty Tbutton i jeden Tedit na formie Form1, rozmieść je i podczep przyciski do akcji jak pokazano poniżej. Podłącz DBGrid1 i DBNavigator1 do DataModule2.DataSource1. 15. Napisz obsługę zdarzenia OnChange dla Edit1. Aplikacja klienta jest gotowa uruchom ją i przetestuj przez chwile. Gdy napiszemy coś w linii edycyjnej na dole aplikacji, to co napisaliśmy jest wpisywane do własności DataModule2.ComputerName. Gdy przyciśniemy przycisk Refresh gdy jest uruchomiony serwer DCOM, pakiety danych są odbierane od serwera i zapisane w pamięci podręcznej ClientDataSet1. Przycisk Refresh jest dostępny gdy nie ma zmian w pakiecie danych. Gdy przyciśniemy przycisk Apply, serwer będzie uzupełniał zmiany w bazie bazując na własności Delta. Gdy tylko serwer zwróci pakiet danych error log do klienta, aplikacja serwera wyłączy się. Dla szybszego działania aplikacji serwera można uruchomić ją ręcznie z Explorera Windows. Aplikacja klienta nie przechowuje stale referencji do aplikacji serwera. Jest ona określana przez własność DataModule2.MyServer i jest zwalniana gdy kończymy aplikacje. Tym sposobem aplikacja oszczędza zasoby systemowe aplikacji serwera co zwiększa ogólną skalowalność tego rozwiązania.