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

Podobne dokumenty