Wykład 8 - Instytut Informatyki Teoretycznej i Stosowanej
Transkrypt
Wykład 8 - Instytut Informatyki Teoretycznej i Stosowanej
Oprogramowanie systemów równoległych i rozproszonych Wykład 8 Dr inż. Tomasz Olas [email protected] Instytut Informatyki Teoretycznej i Stosowanej Politechnika Cz˛estochowska Wykład 8 – p. 1/4 Standard CORBA CORBA (Common Object Request Broker Architecture) jest standardem przeznaczonym do kompleksowego tworzenia obiektowych aplikacji rozproszonych. Specyfikacja technologii CORBA została opracowana przez konsorcjum OMG (Object Management Group) utworzone w 1989 r. Zajmuje sie˛ ono rozwojem, adaptacja˛ i promowaniem standardów dla rozwijania i rozpowszechniania aplikacji heterogenicznych i rozproszonych. Skupia ponad 800 czołowych firm rozwojowych, producentów sprz˛etu komputerowego oraz dostawców oprogramowania a także użytkowników (m. in. takie firmy jak: Apple, AT&T Digital, HP, Intel, Inprise, IBM, Novell, Oracle, Software AG, Sybase, Symantec, Xerox itd). Wykład 8 – p. 2/4 Model komunikacji Centralnym elementem architektury CORBA jest ORB (Object Request Broker) jest odpowiedzialny za wszystkie operacje, jakie sa˛ dokonywane pomiedzy ˛ klientem a programem implementujacym ˛ usługi, czyli serwerem. Wykład 8 – p. 3/4 Zalety (I) Otwartość. Architektura CORBA jest otwartym rozwiazaniem ˛ opartym na opublikowanej specyfikacji. Uniwersalność. Jest niezależna od sprz˛etu i systemu operacyjnego. Współdziałajace ˛ komponenty moga˛ działać na różnych architekturach sprz˛etowych i pod kontrola˛ różnych systemów operacyjnych. (Jest zaimplementowana i obsługiwana na wielu różnych systemach operacyjnych). Elastyczność. Obiekt programowy zgodny z architektura˛ CORBA posiada ściśle zdefiniowany interfejs, poprzez który odbywa sie˛ komunikacja. Zmiany w implementacji obiektu nie maja˛ wpływu na inne obiekty, o ile nie zostanie zmieniony interfejs. Współpraca. Komunikacja pomiedzy ˛ obiektami programowymi zgodnymi z CORBA odbywa sie˛ przy wykorzystaniu protokołu IIOP. Obiekty programowe moga˛ ze soba˛ w pełni współpracować, nawet jeżeli działaja˛ na różnych systemach operacyjnych i zostały utworzone z wykorzystaniem różnych jezyków ˛ programowania. Wykład 8 – p. 4/4 Zalety (II) Przenośność. Obiekty programowe zgodne ze standardem CORBA sa˛ przenośne. To znaczy, że obiekty zbudowane na jednej platformie moga˛ być wykorzystane na każdej innej z obsługiwanych platform. Obiektowość. Budowa aplikacji odbywa sie˛ zgodnie z zasadami techniki obiektowej. Przeźroczystość dost˛epu. Z punktu widzenia użytkownika (programisty) nie ma różnicy pomiedzy ˛ dostepem ˛ do lokalnych i zdalnych obiektów. Przeźroczystość położenia. Jest możliwy dostep ˛ do obiektów bez konieczności określania ich położenia. Wykład 8 – p. 5/4 Usługi CORBA usługa nazewnictwa (naming service) umożliwia obiektom wzajemna˛ lokalizacje˛ przy wykorzystaniu ich nazw, usługa zdarzeń (event service) pozwala obiektom być subskrybentem kanału zdarzeń dzieki ˛ czemu moga˛ oni być powiadamiani o wystapieniu ˛ określonych zdarzeń, usługa transakcji (transaction service) definiuje reguły transakcyjności, koordynuje dwufazowe zatwierdzanie operacji pomiedzy ˛ obiektami, usługa bezpieczeństwa (security service) zapewnia funkcje˛ autentyfikacji, autoryzacji i szyfrowania. Służa˛ one do ochrony danych i kontroli dostepu ˛ użytkowników do aplikacji i usług. Wykład 8 – p. 6/4 Schemat architektury aplikacji w Corbie Wykład 8 – p. 7/4 Struktura mechanizmu ORB Warstwa ORB stanowi centralny obiekt Corby. Dlatego sposób jego budowy decyduje o tym, że Corba to technologia niezależna od platformy sprz˛etowo–programowej. W architekturze ORG zdefiniowano pojecie ˛ mostu, który odpowiada za dostep ˛ do implementacji obiektu oraz komunikacje˛ z klientem. Most jest odpowiedzialny za unifikacje˛ danych przekazywanych w warstwie ORB. Pozwala on również na tworzenie domen, które odpowiedzialne sa˛ za poszczególne obiekty Corby (umożliwia to np. ograniczenie dostepności ˛ pewnych obiektów, do których maja˛ dostep ˛ tylko klienci z wybranej dziedziny. Wykład 8 – p. 8/4 Komunikacja miedzy ˛ domenami ORB Za komunikacje˛ wewnatrz ˛ domeny odpowiada protokół o nazwie GIOP (The General Inter-ORB Protocol). Główne jego zadanie to zapewnienie komunikacji poszczególnym obiektom ORB. Do komunikacji pomiedzy ˛ domenami ORB została utworzona specyfikacja protokołu IIOP (Internet Inter-ORB Protocol). IIOP wykorzystuje stos TCP/IP do komunikacji. Dzieki ˛ protokołom GIOP i IIOP możliwy jest dostep ˛ do Corby z poziomu różnych, nawet bardzo odmiennych od siebie, jezyków ˛ programowania. Wykład 8 – p. 9/4 Adapter obiektu Realizacja wywołania zdalnej metody w Corbie wymaga, aby po stronie serwera znajdował sie˛ mechanizm, który jest odpowiedzialny za bezpieczeństwo tej operacji, utworzenia referencji do obiektu oraz za aktywacje˛ implementacji. Taki mechanizm nazywa sie˛ adapterem obiektu. W chwili obecnej CORBA zawiera dwa podstawowe typy adapterów: Adapter BOA (Basic Object Adapter) charakteryzuje sie˛ niskim poziomem skomplikowania w implementacji. Jego wada˛ jest ograniczenie tylko do podstawowych operacji. Z tego powodu wielu producentów serwerów Corby dodaje do niego własne rozwiazania, ˛ co powoduje brak zgodności pomiedzy ˛ różnymi implementacjami. Adapter POA (Portable Object Adapter) zastepuje ˛ adapter BOA i zawiera brakujace ˛ operacje, które nie wystepuj ˛ a˛ w adapterze BOA. Wykład 8 – p. 10/4 Wywołanie zdalnych operacji Dostep ˛ do zdalnych obiektów może odbywać sie˛ w sposób statyczny lub dynamiczny: Statyczne wywołanie operacji nastepuje ˛ poprzez pieniek IDL (ang. IDL stub). Programista specyfikuje pieniek wykorzystujac ˛ jezyk ˛ IDL. Pieniek jest funkcja˛ klienta, która pozwala statycznie wywoływać zdalne operacje poprzez wywołanie „zwykłej” lokalnej funkcji (badź ˛ metody w przypadku jezyka ˛ obiektowego np. C++). Dynamiczne wywołanie operacji. Aplikacja może w trakcie działania może dokonać specyfikacji usługi, która jest wymagana. Niezbedna ˛ jest przy tym informacja o interfejsie i o niezbednych ˛ typach. Taka˛ informacje˛ można otrzymać od programisty lub programowo z interfejsu repozytorium. Wykład 8 – p. 11/4 Repozytorium Interfejsu Repozytorium Interfejsu umożliwia uzyskanie dostepu ˛ do interfejsów obiektów, operacji jakie sa˛ przez nie udostepnione ˛ oraz parametrów i typów jakie sa˛ w nich wykorzystywane. Można je traktować jako baz˛e danych zawierajac ˛ a˛ definicje˛ obiektów. Repozytorium interfejsu zawiera te same informacje, które znajduja˛ sie˛ w plikach IDL. Wykład 8 – p. 12/4 Repozytorium Implementacji Repozytorium Implementacji zawiera informacje o klasach serwera, instancjach obiektów i ich identyfikatorach. Wykorzystywane jest do zarzadzania ˛ obiektami. Używane jest również do lokalizacji i aktywacji zaimplementowanych obiektów. Obiekt po zarejestrowaniu w Repozytorium Implementacji uruchamiany jest automatycznie w momencie wystapienia ˛ żadania ˛ od klienta. Wykład 8 – p. 13/4 Tworzenie aplikacji Proces tworzenia aplikacji z wykorzystaniem technologii CORBA można podzielić na nastepuj ˛ ace ˛ etapy: zdefiniowanie interfejsów obiektów w IDL, generacja kodu pieńka klienta przy wykorzystaniu kompilatora IDL, utworzenie implementacji obiektu po stronie serwera (servant), utworzenie kodu klienta, utworzenie kodu serwera. Wykład 8 – p. 14/4 OMG IDL OMG IDL (Interface Definition Language - jezyk ˛ definiowania interfejsu) jest podstawowym mechanizmem w Corbie umożliwiajacym ˛ odseparowanie interfejsu obiektu (deklaracji obiektu) od jego implementacji. Jest jezykiem ˛ typowo deklaracyjnym i nie pozwala na realizacje˛ obiektów. Gramatyka jezyka ˛ IDL jest podzbiorem ANSI C++ z dodatkowymi konstrukcjami, wspierajacymi ˛ mechanizm wywoływania operacji. Wykład 8 – p. 15/4 Składnia OMG IDL Wykład 8 – p. 16/4 OMG IDL - typy danych (I) typy podstawowe: Wykład 8 – p. 17/4 OMG IDL - typy danych (II) typy definiowane Deklaracja typu definiowanego (typedef) może być używana w celu przypisania nazwy do definicji dowolnego typu, np. typedef string MemoVal; W praktyce, typedef wykorzystuje sie˛ dla tablic i typów szablonowych. tablice IDL dostarcza możliwości tworzenia wielowymiarowych tablic stałego rozmiaru do przechowywania elementów dowolnego typu. Rozmiar każdego wymiaru musi być określony w definicji, np. typedef long CellValues[10][20]; Należy używać typedef dla tablic, które sa˛ używane jako parametr, atrybut lub wartość zwracana. Wykład 8 – p. 18/4 OMG IDL - typy danych (III) typy szablonowe sekwencja (sequence) Sekwencja jest zmiennej długości lista˛ elementów dowolnego typu IDL. Sekwencje możemy określić jako jednowymiarowa˛ tablice˛ zmiennej długości. Długość sekwencji może być ograniczona (określamy jej maksymalny rozmiar) lub nie. typedef sequence <octet,10> s1; typedef sequence <octet> s2; string String jest sekwencja˛ znaków (char). Podobnie jak sekwencja może być ograniczony lub nie: typedef string <15> Name; typedef string Description; Wykład 8 – p. 19/4 OMG IDL - typy danych (IV) typ wyliczeniowy Jest to najprostszy z typów konstrukcyjnych. Przykład: enum Pet{cat, dog, fish, bird, rat, horse}; struktury Struktura podobnie jak kilka elementów w IDL, ma te same możliwości jak w C++, a ponadto umożliwia tworzenie typów rekurencyjnych. Przykład: struct Osoba{ string<10> imie; string<10> nazwisko; long rok_urodzenia; }; Wykład 8 – p. 20/4 OMG IDL - typy danych (V) Unie Unia w IDL zawiera identyfikator pola określajacy, ˛ która zmienna składowa unii jest bieżaco ˛ przypisana z wartościa. ˛ union nazwa_unii switch(typ) { case wielkość_stała_1: typ nazwa1; case wielkość_stała_2: typ nazwa2; ... default: typ nazwa; }; Przykład: union Reference switch(short){ case 1:{Title: string; Author: string;} case 2: URL: string; case 3: TopicID: long; }; Wykład 8 – p. 21/4 OMG IDL - moduł Moduł w IDL pełni role˛ głównie porzadkow ˛ a˛ (jest opcjonalny). Stanowi przestrzeń nazw i z tego powodu, gdy IDL jest tłumaczony na C++ jest automatycznie zamieniany na namespace. module BazaDanych { ... } Istnieje możliwość ponownego otwierania przestrzeni nazw, jaka˛ stwarza moduł: module Modul1 { ... } module Modul2 { ... } module Modul1 { ... } Wykład 8 – p. 22/4 OMG IDL - stałe IDL zezwala na deklaracje stałych - wykorzystane jest przy tym słowo kluczowego const: const unsigned long LenghtOfNameString=15; W IDL nie sa˛ obsługiwane stałe typu octet. Liczby całkowite moga˛ być określane z użyciem dziesietnej ˛ (ang. decimal), ósemkowej (ang. octal) lub szesnastkowej (ang. hexadecimal) notacji. Wykład 8 – p. 23/4 OMG IDL - interfejsy (I) Interfejsy (ang. Interfaces) - definiuja˛ zbiór metod (operacji), które moga˛ być wywoływane klient. Można rozumieć je jako definicje˛ klasy, bez zawartej w niej sekcji implementacyjnej. Interfejsy sa˛ deklarowane z użyciem słowa kluczowego interface. Wewnatrz ˛ deklaracji interfejsu jest lista atrybutów i metod. Wszystkie metody sa˛ publiczne. Przykład: interface Example1 { readonly attribute string Name; attribute long Value; long AddToValue(in long Summand, out long Resualt); }; Wykład 8 – p. 24/4 OMG IDL - interfejsy (II) IDL dopuszcza trzy typy interfejsu: interfejs abstrakcyjny (abstract)- stanowiacy ˛ podstaw˛e hierarchii obiektowej stosowanej w danej aplikacji, interfejs lokalny (local), interfejs zwykły, który stanowi obiekt publiczny w środowisku aplikacji. Zapis interfejsu przedstawia sie˛ nastepuj ˛ aco: ˛ {abstract | local} interface <nazwa> {:} {lista dziedziczenia} { ... } Wykład 8 – p. 25/4 OMG IDL - atrybuty Interfejs może posiadać atrybuty. Atrybuty w przeciwieństwie do innych obiektowych jezyków ˛ programowania sa˛ tylko publiczne. Deklaracja atrybutu w interfejsie jest poprzedzona słowem kluczowym attribute. Dodanie słowa kluczowego readonly powoduje, iż nowo zadeklarowany atrybut jest przeznaczony tylko do odczytu. Przykład: attribute float liczba; readonly attribute double suma; Wykład 8 – p. 26/4 OMG IDL - wyjatki ˛ Każdy interfejs może definiować wiele wyjatków ˛ (ang. exceptions), które zgłaszane sa˛ momencie wystapienia ˛ błedu ˛ w trakcie wykonania operacji. interface Konto { exception BrakSrodkow { }; ... }; Po słowie kluczowym raises wystepuje ˛ lista wyjatków, ˛ które moga˛ być zgłaszane podczas wykonania operacji. Podczas wykonania operacji moga˛ być zgłaszane również wyjatki ˛ standardowe sygnalizowane przez ORB, które nie musza˛ być wymieniane po słowie raises. Wykład 8 – p. 27/4 OMG IDL - metody (I) Deklaracja metody zawiera typ zwracanej wartości, nazw˛e metody oraz jej parametry. Każdy parametr musi zawierać słowo kluczowe określajace ˛ kierunek przesyłanego parametru, typ parametru i jego nazw˛e. Stosowane sa˛ nastepuj ˛ ace ˛ słowa kluczowe: in (kierunek wejściowy), out (kierunek wyjściowy), inout (kierunek wejściowo - wyjściowy). Klient po wywołaniu metody jest blokowany - oczekuje na zakończenie działania operacji i na zwrócona˛ wartość. W przypadku, gdy klient nie musi czekać na zwracana˛ wartość, to należy ja˛ zadeklarować z użyciem słowa kluczowego oneway przed typem zwracanej wartości. Wykład 8 – p. 28/4 OMG IDL - metody (II) W celu określenia możliwości wystapienia ˛ wyjatków ˛ w metodzie należy użyć słowa kluczowego raises, po którym w nawiasach okragłych ˛ po przecinku należy wymienić nazwy wyjatków. ˛ Wyjatki ˛ powinny być zdefiniowane wcześniej słowem kluczowym exception. Przykład: interface Calka { double Suma(in double a, in double b); double Iloczyn(in double a, in double b); } interface Drzewo { exception ObiektIstnieje { }; void NowyElement(in double a) raises(ObiektIstnieje); oneway void Reorganizacja(); }; Wykład 8 – p. 29/4 OMG IDL - dziedziczenie CORBA dopuszcza możliwość dziedziczenia przez interfejs atrybutów i metod innych interfejsów. interface Baza { ... }; interface InterfejsPochodny: Baza { ... }; CORBA umożliwia dziedziczenie wielokrotne, o ile interfejsy przodków nie maja˛ definicji z identyczna˛ nazwa. ˛ Wszystkie interfejsy IDL dziedzicza˛ bezpośrednio od „CORBA interface object”. Wykład 8 – p. 30/4 OMG IDL - dyrektywy preprocesora W plikach IDL moga˛ zostać wykorzystane dyrektywy preprocesora: #define #elif #else #endif #ifdef #ifndef #include Przykład: #include <baza.idl> Wykład 8 – p. 31/4 Interfejs obiektu w IDL Plik kalkulator.idl: interface Kalkulator { double dodaj(in double x1, in double x2); }; Wykład 8 – p. 32/4 Generacja szkieletu w C++ W przypadku implementacji omniORB kompilator IDL nazywa sie˛ omniidl. Standardowo do wygenerowania kodu w jezyku ˛ C++ wykorzystywana jest opcja -bcxx: omniidl -bcxx kalkulator.idl w wyniku otrzymujemy dwa pliki: kalkulator.hh kalkulatorSK.cc Po dodaniu opcji -Wbexample (omniidl -bcxx -Wbexample hello.idl) wygenerowany zostaje ponadto plik kalkulator_i.cc. Wykład 8 – p. 33/4 POA - architektura (I) POA zawiera kilkanaście komponentów dość precyzyjnie zdefiniowanych w specyfikacji: Klient - Program wywołujacy ˛ operacje na obiektach poprzez ich referencje. ˛ Serwer - Program odpowiedzialny za realizacje˛ zadań stawianych przez klienta. Zawiera implementacje˛ obiektów servant oraz POA. Obiekt - W architekturze POA oznacza abstrakcyjna˛ jednostk˛e zdefiniowana˛ dzieki ˛ technologii CORBA. Każdy obiekt zawiera identyfikator, interfejs i implementacje˛ interfejsu. Servant - Stanowi jednostk˛e (obiekt) w jezyku ˛ programowania użytym do implementacji interfejsu. Jest to element programu serwera. Menadżer servant - Obiekt tworzony przez programiste, ˛ przeznaczony do kontroli poszczególnych obiektów servant (np. do ich tworzenia oraz usuwania). Wykład 8 – p. 34/4 POA - architektura (II) komponenty POA cd.: ObjectID - Identyfikator obiektu - jest niepowtarzalnym ciagiem ˛ wartości typu octec (może być wygenerowany przez system lub podany przez użytkownika). Referencja obiektu - Służy do określania położenia obiektu oraz zawiera identyfikatory nadane przez POA. Policy - Definiuje zachowanie obiektów implementowanych przez POA. POA - Jednostka składowa programu serwera (zawiera pozostałe elementy architektury jak servant czy inne obiekty POA). Menadżer POA - Umożliwia zmiane˛ stanów obiektów POA (kolejkowanie poszczególnych żada ˛ ń, odrzucanie, tworzenie nowych oraz usuwanie obiektów POA). Wykład 8 – p. 35/4 Hierarchia obiektów POA Obiekty POA tworza˛ hierarchie. ˛ Pierwszym obiektem wystepuj ˛ acym ˛ w każdym serwerze jest korzeń hierarchii POA (RootPOA). W przeciwieństwie do pozostałych obiektów POA korzeń zawsze jest dostepny ˛ i nie trzeba go tworzyć. Pozostałe obiekty POA moga˛ być tworzone przy użyciu RootPOA badź ˛ przez menadżera POA. Zadaniem obiektów POA jest przechowywanie obiektów servant. Wykład 8 – p. 36/4 AOM Obiekt POA zawiera specjalny obiekt o nazwie Active Object Map (AOM) - mapa aktywnych obiektów. Gdy do obiektu POA przychodzi żadanie ˛ od klienta, adapter sprawdza, czy w AOM istnieje referencja do obiektu. Jeżeli taka referencja istnieje, to odszukiwany jest odpowiedni obiekt servant. W przypadku braku referencji POA odwołuje sie˛ do domyślnego obiektu servant lub do menadżera obiektów servant, których zadaniem jest utworzenie nowego lub odszukanie istniejacego ˛ obiektu servant. Wykład 8 – p. 37/4 Zmiana stanu obiektu POA (I) Każdy obiekt POA jest wyposażony w menadżera, którego zadaniem jest zmiana stanu obiektu POA. Obiekt POA może znajdować sie˛ w jednym z czterech stanów: active - żadania ˛ sa˛ obsługiwane na bieżaco, ˛ holding - żadania ˛ sa˛ dołaczane ˛ do kolejki, discarding - żadania ˛ sa˛ odrzucane, a klient otrzymuje wyjatek ˛ TRANSIENT, inactive - żadania ˛ nie sa˛ obsługiwane, obiekt POA jest w trakcie procedury usuwania. Wykład 8 – p. 38/4 Zmiana stanu obiektu POA (II) Po wywołaniu metody create_POA obiekt POA znajduje sie˛ w stanie holding. Przetwarzanie żada ˛ ń odbywa sie˛ dopiero po wywołaniu metody activate z menadżera POA. Usuniecie ˛ obiektu może zostać wykonane poprzez przez wywołanie metody menadżera deactivate. Wykład 8 – p. 39/4 CORBA - przykład Proces tworzenia aplikacji z wykorzystaniem technologii CORBA można podzielić na nastepuj ˛ ace ˛ etapy: zdefiniowanie interfejsów obiektów w IDL, generacja kodu pieńka klienta przy wykorzystaniu kompilatora IDL, utworzenie implementacji obiektu po stronie serwera (servant), utworzenie kodu klienta, utworzenie kodu serwera. Wykład 8 – p. 40/4 Interfejs obiektu w IDL Plik hello.idl: interface Hello { string say_hello(in string client); }; Wykład 8 – p. 41/4 Generacja szkieletu w C++ W przypadku implementacji omniORB kompilator IDL nazywa sie˛ omniidl. Standardowo do wygenerowania kodu w jezyku ˛ C++ wykorzystywana jest opcja -bcxx: omniidl -bcxx hello.idl w wyniku otrzymujemy dwa pliki: hello.hh helloSK.cc Po dodaniu opcji -Wbexample (omniidl -bcxx -Wbexample hello.idl) wygenerowany zostaje ponadto plik hello_i.cc. Wykład 8 – p. 42/4 hello.hh (I) class Hello; class _objref_Hello; class _impl_Hello; typedef _objref_Hello* Hello_ptr; typedef Hello_ptr HelloRef; class Hello { public: // Declarations for this interface type. typedef Hello_ptr _ptr_type; typedef Hello_var _var_type; static static static static _ptr_type _ptr_type _ptr_type _ptr_type _duplicate(_ptr_type); _narrow(CORBA::Object_ptr); _unchecked_narrow(CORBA::Object_ptr); _nil(); // ... for internal use }; class _objref_Hello : public virtual CORBA::Object, public virtual omniObjRef { public: char* say_hello(const char* client); // ... for internal use }; Wykład 8 – p. 43/4 hello.hh (II) class _impl_Hello : public virtual omniServant { public: virtual ~_impl_Hello(); virtual char* say_hello(const char* client) = 0; ... }; class POA_Hello : public virtual _impl_Hello, public virtual PortableServer::ServantBase { public: virtual ~POA_Hello(); inline ::Hello_ptr _this() { return (::Hello_ptr) _do_this(::Hello::_PD_repoId); } }; Wykład 8 – p. 44/4 Servant class Hello_impl : public POA_Hello { public: virtual char * say_hello(const char * client); }; char * Hello_impl::say_hello(const char * client) { cout << "omniORB C++ server: " << client << endl; char * server = CORBA::string_alloc(32); strncpy(server, "omniORB C++ server", 32); return server; } Wykład 8 – p. 45/4 Serwer Typowe czynności jakie powinien wykonać serwer moga˛ wygladać ˛ nastepuj ˛ aco: ˛ nawiazanie ˛ kontaktu z ORB, uzyskanie obiektu-korzenia POA, odczytanie menadżera, utworzenie obiektu zawierajacego ˛ implementacje interfejsu, aktywacja implementacji, zapis IOR, aktywacja menadżera, uruchomienie petli ˛ zdarzeń ORB. Wykład 8 – p. 46/4 Usługa nazw Klient może na różne sposoby uzyskać referencje do zdalnego obiektu. Wygodnym mechanizmem jaki może być w tym celu wykorzystany jest mechanizm o nazwie usługa nazw (Naming Service). Umożliwia ona na identyfikacje obiektów posługujac ˛ sie˛ ich nazwami symbolicznymi. Wykład 8 – p. 47/4 Kod serwera II int main(int argc, char ** argv) { try { CORBA::ORB_ptr orb = CORBA::ORB_init(argc, argv); CORBA::Object_var poa_obj = orb->resolve_initial_references("RootPOA"); PortableServer::POA_var poa = PortableServer::POA::_narrow(poa_obj); PortableServer::POAManager_var manager = poa->the_POAManager(); Hello_impl * service = new Hello_impl; try { CORBA::Object_var ns_obj = orb->resolve_initial_references("NameService"); if (!CORBA::is_nil(ns_obj)) { CosNaming::NamingContext_ptr nc = CosNaming::NamingContext::_narrow(ns_obj); CosNaming::Name name; name.length(1); name[0].id = CORBA::string_dup("TestServer"); name[0].kind = CORBA::string_dup(""); nc->rebind(name, service->_this()); cout << argv[0] << ": server ’TestServer’ bound" << endl; } } catch (CosNaming::NamingContext::NotFound &) { cerr << "not found" << endl; } catch (CosNaming::NamingContext::InvalidName &) { cerr << "invalid name" << endl; } catch (CosNaming::NamingContext::CannotProceed &) { cerr << "cannot proceed" << endl; } manager->activate(); orb->run(); delete service; orb->destroy(); } catch (CORBA::UNKNOWN) { cerr << "unknown exception" << endl; } catch (CORBA::SystemException &) { cerr << "system exception" << endl; } } Wykład 8 – p. 48/4 Kod klienta II int main(int argc, char ** argv) { try { CORBA::ORB_ptr orb = CORBA::ORB_init(argc, argv); Hello_ptr hello = 0; try { CORBA::Object_var ns_obj = orb->resolve_initial_references("NameService"); if (!CORBA::is_nil(ns_obj)) { CosNaming::NamingContext_ptr nc = CosNaming::NamingContext::_narrow(ns_obj); CosNaming::Name name; name.length(1); name[0].id = CORBA::string_dup("TestServer"); name[0].kind = CORBA::string_dup(""); CORBA::Object_ptr obj = nc->resolve(name); if (!CORBA::is_nil(obj)) { hello = Hello::_narrow(obj); } } } catch (CosNaming::NamingContext::NotFound &) { cerr << "not found" << endl; } catch (CosNaming::NamingContext::InvalidName &) { cerr << "invalid name" << endl; } catch (CosNaming::NamingContext::CannotProceed &) { cerr << "cannot proceed" << endl; } if (!CORBA::is_nil(hello)) { char * server = hello->say_hello("omniORB C++ client"); cout << "answer from: " << server << endl; CORBA::string_free(server); } orb->destroy(); } catch (CORBA::UNKNOWN) {} } Wykład 8 – p. 49/4