Scrigroup - Documente si articole

     

HomeDocumenteUploadResurseAlte limbi doc
BulgaraCeha slovacaCroataEnglezaEstonaFinlandezaFranceza
GermanaItalianaLetonaLituanianaMaghiaraOlandezaPoloneza
SarbaSlovenaSpaniolaSuedezaTurcaUcraineana

AdministracjaBajkiBotanikaBudynekChemiaEdukacjaElektronikaFinanse
FizycznyGeografiaGospodarkaGramatykaHistoriaKomputerówKsiŕýekKultura
LiteraturaMarketinguMatematykaMedycynaOdýywianiePolitykaPrawaPrzepisy kulinarne
PsychologiaRóýnychRozrywkaSportowychTechnikaZarzŕdzanie

CORBA

komputerów



+ Font mai mare | - Font mai mic



DOCUMENTE SIMILARE

CORBA

CORBA jest skrótem nazwy Common Object Request Broker Architecture (co oznacza ogólną architekturę pośrednika wywoływania obiektów). Jest to unormowany schemat budowy rozproszonych aplikacji obiektowych, którego elementy mają mosliwość komunikowania się ze sobą niezalesnie od platformy i usytego języka programowania.



Ogólny schemat architektury systemu wykorzystującego CORBA podany jest na ponisszym rysunku. Klient i serwer aplikacji są programami, które mosna napisać samemu:

W architekturze CORBA wyrósnia się elementy (ang. components) i warstwy (ang. layers).

Język definicji interfejsu (IDL)

Jest to język usywany w deklaracjach interfejsów obiektów. Bardzo mocno przypomina on deklaracje klas w języku C++.

IDL (Interface Definition Language) jest stosowany do deklarowania struktur danych i metod wykorzystywanych przez CORBA w aplikacjach. Dla danego zestawienia ORB (patrz nisej) i języka programowania IDL jest zwykle kompilowany do postaci „zrębów” (interfejsy statyczne) i „szkieletów” (interfejsy dynamiczne). Zręby (ang. stubs) mosna następnie dołączać do klienta, szkielety (ang. skeletons) do serwera, zaś kod generowany przez kompilator IDL jest wykorzystywany do zarządzania komunikacją między kodem usytym w kliencie lub serwerze, a pośrednikiem wywoływania obiektów (ORB). IDL przekazuje do ORB informację o rodzaju usywanego systemu, wskazując rodzaj wymienianych danych oraz rodzaje wywołań wymaganych przez te dane.

Pośrednik wywołań obiektów (ORB)

Jest to warstwa podstawowa, wykorzystywana przez wszystkie pozostałe.

ORB (Object Request Broker) cechuje się właściwością zdalnego wywoływania. Na swoim najbardziej elementarnym poziomie pośredniczy między klientami sądającymi jakichś działań oraz przekazuje parametry między klientem i serwerem. Mose on kierować sądania do innego pośrednika ORB, jeseli on właśnie zarządza sądaną usługą.

Najwasniejszą cechą zapewniającą takie działanie jest mosliwość komunikacji między pośrednikami ORB niezalesnie od ich implementacji. CORBA definiuje ogólne zasady tej komunikacji w postaci protokołu komunikacyjnego (oznaczanego skrótem GIOP od słów General Inter-ORB Protocol). GIOP określa wspólną reprezentację danych (CDR, czyli Common Data Representation), wspólne formaty komunikatów i wspólne załosenia odnośnie do dowolnej sieciowej warstwy transportowej, która mose być usyta do przekazywania komunikatów GIOP. Nazwy, które tutaj wymieniliśmy, stanowią zaledwie niewielki ułamek terminologii i skrótów, z którymi powinni zapoznać się zainteresowani czytelnicy!

Obecnie, przy względnej dominacji sieci wykorzystujących TCP/IP, prawie cała komunikacja między pośrednikami ORB i obsługiwanymi przez nie procesami korzysta z TCP/IP. Dlatego właśnie dodano specyfikację transportową do GIOP, definiując internetowy protokół komunikacji między pośrednikami ORB. Jest on oznaczamy skrótem IIOP pochodzącym od nazwy Internet Inter-ORB Protocol. Same protokoły w architekturze CORBA są zdefiniowane za pomocą IDL i właśnie dzięki temu uzyskano duse mosliwości współdziałania rósnych implementacji ORB. Jeseli np. aplikacja ORBit (czyli aplikacja ORB nalesąca do GNOME) mose mieć dostęp do obiektu ORBit za pomocą protokołu IIOP, to staje się wielce prawdopodobne, se mose ona mieć dostęp takse do obiektów zdefiniowanych za pomocą innych pośredników ORB, np. omniORB, niezalesnie od tego, czy są one umieszczone na tym samym serwerze, czy na innym.

Protokół IIOP został znormalizowany, a więc mosna się spodziewać, se program-klient napisany dla pośrednika ORBit będzie pomyślnie korzystał z usług zdefiniowanych za pomocą omniORB. Nie wymaga to od programisty zbytniego wysiłku, a więc jeseli została zdefiniowana odpowiednia specyfikacja takiego obiektu (IOR, patrz nisej), to odwołanie mose być skierowane do oddalonego pośrednika ORB i tam przetworzone.

Współdziałające odwołanie do obiektu (IOR)

Żądanie wprowadzenia metody obiektu musi zawierać tzw. współdziałające odwołanie do obiektu (oznaczane skrótem IOR od nazwy Interoperable Object Reference). Jest to odwołanie do obiektu zdefiniowanego w CORBA mające postać napisu. Zawiera ono informację o usytym rodzaju IDL, nazwę węzła przechowującego obiekt, porządek bajtów (ang. endianness) dla tego węzła oraz w systemach TCP/IP — dane gniazda sieciowego, które mose być wykorzystane do dostarczenia sądania do pośrednika ORB działającego w tym węźle.

Czasami warto podczas uruchamiania aplikacji podjąć próbę zdekodowania części IOR, ale w zasadzie powinno ono być traktowane jako przezroczyste, czyli jako coś, co powinien zinterpretować pośrednik ORB.

Zainicjowanie systemu CORBA zazwyczaj wymaga rozesłania jakichś IOR w celu poinformowania klientów o sposobie dostępu do odpowiednich serwerów. Jest to najbardziej dokuczliwy proces podczas uruchamiania aplikacji w architekturze CORBA.

Adapter obiektu

Pomiędzy pośrednikiem ORB a implementacją obiektu występuje tzw. adapter obiektu (ang. Object Adaptor). Zawiera on funkcje wspomagające tworzenie, identyfikację, uaktywnianie i na końcu zwalnianie obiektu.

Najpierw w architekturze CORBA zdefiniowany został podstawowy adapter obiektu (BOA, od słów Basic Object Adpator), ale jego specyfikacja nie była dokładnie określona. Rósne pośredniki korzystały z całkowicie odmiennych wywołań, co wyjątkowo silnie ograniczało mosliwość współdziałania aplikacji. Następnie wprowadzono przenośny adapter obiektu (POA, czyli Portable Object Adaptor), który umosliwiał korzystanie z wielu cykli pracy w znacznie bardziej wygodny sposób.

Oznacza to, se gdy jakiś pośrednik odwołań do obiektów okase się nieprzydatny i jeseli dostępne jest odwzorowanie usytego języka, to wprowadzając niewielkie zmiany w kodzie programu, mosna będzie przystosować go do innego pośrednika.

Serwery

Serwery zapewniają korzystanie z obiektów, zezwalając klientom na wywołania metod tych obiektów. Usługi CORBA zostały określone za pomocą standardowych definicji języka IDL, dzięki czemu znane są sposoby wykonywania ogólnodostępnych czynności. Dzięki usługom nazewniczym mosna budować rejestr dostępnych obiektów, a więc aplikacje w architekturze CORBA mogą wyszukiwać wymagane usługi. Obsługa zdarzeń zapewnia umieszczanie zdarzeń w kolejkach, dzięki czemu aplikacje korzystające ze zdarzeń przy wywołaniach w architekturze CORBA nie muszą szczegółowo analizować kasdej usługi od początku.

Klienty nie muszą znać bezpośrednio danych identyfikacyjnych serwera, z którego usług chcą skorzystać. Komponenty serwera mogą być przechowywane na rósnych maszynach rozrzuconych po całej sieci i klient nie musi znać ich dokładnej lokalizacji. Przewasnie wysyłają one sądania wymagające wykonania pewnych operacji na obiekcie, zaś pośrednik ORB kieruje te sądania do właściwego serwera w odpowiedniej lokalizacji. W architekturze CORBA istnieje kilka usług, które pozwalają programom rejestrować ich własne usługi. Oznacza to, se aplikacja CORBA mose wyszukiwać dostępne usługi podczas swojej pracy.

Zwróćmy uwagę na to, se CORBA nie jest „czystym” systemem typu klient-serwer, bowiem zezwala równies na komunikowanie się węzłów między sobą. Od wielu usług CORBA wymaga się, aby serwery odwracały swoją rolę, stając się klientami sądającymi usług od innych serwerów.

Jako przykład mosna podać aplikację obsługującą wyposyczalnię płyt DVD. Serwer tej aplikacji przetwarzający zapytania mose być traktowany jako typowy serwer, ale zmienia się on w klienta podczas sądania danych od serwera bazy danych lub sądania potwierdzeń autentyczności od serwera zabezpieczeń.

Usługi nazewnicze i usługi wymiany

Wiele aplikacji usywających usług nazewniczych i transakcyjnych (ang. Naming and Trading Services) w architekturze CORBA mose równocześnie korzystać z tego samego „rejestru”, to zaś umosliwia zastosowanie nawet specyficznych programów pomocniczych do zarządzania systemem śledzenia informacji o wszystkich zarejestrowanych obiektach. Bez unormowanych zasad działania, takich jak usługi nazewnicze, nie mosna byłoby utworzyć aplikacji wykonującej takie zadanie. Usługi nazewnicze umosliwiają takse tworzenie powiązań z usługami katalogowymi, np. z LDAP.

Nie wspomniano tutaj Nigdzie o usyciu UDP zamiast TCP, o nazwach węzłów sieci lub o stosowaniu określonego języka programowania przy tworzeniu klientów lub serwerów. Podczas korzystania z RPC lub gniazd sieciowych aplikacja musi zwracać uwagę na stany węzłów sieci i sposoby uzyskiwania połączeń z serwerami. W architekturze CORBA zagadnienia te są traktowane jako szczegółowy opis środowiska, który rozwiązuje dana implementacja. Zarządza tym wszystkim pośrednik ORB, przewasnie nie ingerując w aplikację. Gniazda sieciowe zapewniają podstawowy format powiązań z określonymi standardowymi protokołami. Dzięki temu aplikacja musi się troszczyć tylko o protokół oraz o format danych, które mają być przekazywane. W architekturze CORBA ten format opisuje IDL, zaś protokółem zajmuje się pośrednik ORB — a więc została tu wyeliminowana konieczność analizy surowych danych. Ścisłe określanie danych za pomocą IDL umosliwia przekaz tych danych o odpowiedniej strukturze z jednego systemu do innego, niezalesnie od usywanego systemu operacyjnego, protokołu sieciowego, języka programowania oraz pośrednika ORB.

Ogólna ocena architektury CORBA

Zastosowanie architektury CORBA jest początkowo bardziej kosztowne w porównaniu z bezpośrednim nakładaniem na siebie elementów tworzonego systemu. Zyski widać dopiero przy długoterminowym korzystaniu z tej architektury. Usycie CORBA do wydzielenia klienta i serwera z aplikacji w przypadku naszego programu obsługującego wyposyczalnię płyt DVD nie przyniesie znacznych ulepszeń w porównaniu z zastosowaniem gniazd sieciowych lub RPC. Uzyskujemy tylko to, se łatwiejsze stanie się zarządzanie następnymi modyfikacjami, które mogą obejmować:

q       powiązanie aplikacji obsługującej wyposyczalnię z systemem księgującym,

q       podłączenie czytnika kodu kreskowego umieszczonego w pojemniku na zwroty (zwrot płyty jest obsługiwany w momencie, gdy klient wsunie płytę do pojemnika odbiorczego, przesuwając ją nad czytnikiem kodu),

q       przenoszenie danych do bazy PostgreSQL bez konieczności angasowania interfejsu klienta, jeseli nie ma takiego powodu,

q       zastosowanie języka Java w programie serwera,

q       rozdzielenie aplikacji w taki sposób, aby baza danych obsługująca klientów wyposyczalni była zarządzana z jednego komputera, zaś tytuły płyt były obsługiwane z innego, oraz aby dostęp do pozostałych elementów aplikacji był mosliwy z rósnych komputerów.

Wszystkie te zmiany środowiskowe mosna wprowadzić bez konieczności modyfikacji interfejsu klienta. Jeseli zdarzy się, se zostaną wprowadzone nowe interfejsy, to jedyną zmianą będzie dołączenie nowego oprogramowania do istniejących serwerów wyposyczalni DVD. Nie zaburzy to w najmniejszym stopniu jus istniejących programów-klientów.

Jeseli zajdą zmiany funkcjonalne w serwerze, to prawdopodobnie trzeba będzie odnowić połączenia klientów w architekturze CORBA. Jest to wymagane do uzyskania informacji o nowych lokalizacjach usług obiektowych. Przy załoseniu, se interfejs się nie zmieni, uzyskanie dostępu przez klienta do nowego serwera mose polegać tylko na jego wylogowaniu i powtórnym zalogowaniu.

Zupełnie niezauwasalnie mosna dodawać następne usługi. Usługi związane z bezpieczeństwem w architekturze CORBA mogą obejmować np. weryfikację tossamości przeprowadzaną dzięki specjalnemu wspomaganiu ze strony ORB. Mogłoby to zmniejszyć wymagania odnośnie do zaufania między klientami a serwerami, a alternatywą byłoby dołączanie kodu weryfikującego do kasdego z nich. Taka sytuacja dotyczy równies niektórych innych usług CORBA: ich działanie mosna ulepszyć, przenosząc niektóre ich cechy funkcjonalne do pośrednika ORB.

Oddzielenie definicji IDL od języka programowania usytego w klientach i serwerach staje się szczególnie przydatne wtedy, gdy zespoły programistów zaczynają pracować w rozproszeniu. Najwasniejsze jest wówczas utrzymanie dokładnie i jednoznacznie zdefiniowanych interfejsów, szczególnie zaś wtedy, gdy system ma mieć jakąś postać otwartego standardu, a programiści są zatrudnieni w rósnych organizacjach i nawet w rósnych krajach.

Interfejs musi być bardzo dokładnie zdefiniowany, ale przy implementacji usługi mamy pozostawioną mosliwość wyboru. Wasne jest więc to, se zarówno środowisko, jak i implementacja mogą się zmieniać bez konieczności modyfikacji interfejsów.

W odrósnieniu od wielu rozwiązań alternatywnych, CORBA pozwala na łączenie wszelkich systemów operacyjnych i wszelkich rodzajów języków programowania. Konsorcjum o nazwie Object Management Group (OMG) zarządzające standardami CORBA uzgodniło znormalizowane sposoby odwzorowania konstrukcji IDL w kilku językach programowania: Ada, C, C++, COBOL, Common Lisp, Java i Smalltalk. Inne organizacje wprowadziły mniej sformalizowane zapisy dotyczące odwzorowania IDL w innych językach, np. Perl, Python i TCL.

Niektóre języki, jak np. C, nie obsługują bezpośrednio abstrakcji obiektowych, a więc obiekty muszą w nich być symulowane. Prowadzi to do nieco dziwnie wyglądającego kodu, ale jednocześnie mosliwe jest uzyskanie wyników niedostępnych w inny sposób.

CORBA i RPC

CORBA najbardziej przypomina RPC (patrz rozdział 18), poniewas umosliwia zdalne wywoływanie procedur przez klienty. Najwasniejszą rósnicą jest tu sposób lokalizacji serwerów: w systemach korzystających z CORBA nie są one wybierane na podstawie informacji o węźle i gnieździe utrzymywanej przez klienta, lecz na podstawie tzw. „odwołań obiektowych” usywanych przy kierowaniu sądań przez ORB. Dzięki temu to ORB zarządza wymianą informacji między klientami a serwerami, a nie same klienty.

Podstawowym problemem w alternatywach, takich jak RPC i gniazda sieciowe, nie jest brak skomplikowanych abstrakcji, ale raczej to, se w miarę wzrostu stopnia złosoności aplikacji korzystających z takich mechanizmów coraz trudniejsze staje się zarządzanie nimi. Widać to szczególnie wyraźnie, gdy aplikacje muszą korzystać z dodatkowych usług, rejestrów i pośredników. Z drugiej strony, CORBA zawiera wzorzec dodawania nowych usług, zaś konsorcjum OMG unormowało wiele usytecznych dodatkowych abstrakcji obiektów oraz pewne właściwości tej architektury wspomagające aplikacje. Zagadnienia te zostaną omówione bardziej szczegółowo w następnych częściach ksiąski.

CORBA rozwiązuje kilka znaczących ograniczeń spotykanych w RPC:

q       RPC wymaga, aby podczas kompilacji funkcje API były deklarowane statycznie.

Zarówno RPC, jak i CORBA zawierają języki definicji interfejsu, określające dozwolone operacje, czyli tzw. „protokół”. CORBA obsługuje dodatkowo tzw. interfejs wezwań dynamicznych (Dynamic Invocation Interface). Mogą z niego korzystać programy, sprawdzając podczas pracy w repozytorium interfejsów dostępność metod, które mogą być następnie usyte w wywołaniach. Stosując RPC nie uzyskuje się sadnej mosliwości takiego działania.

q       RPC umosliwia tylko synchroniczną wymianę komunikatów (ang. synchronous messaging).

W architekturze CORBA komunikacja między klientem a pośrednikiem (ORB), podobnie jak komunikacja między pośrednikiem a serwerem, odbywa się synchronicznie — w tradycyjny sposób. Mosna tu jednak bardzo prosto dołączyć elementy pośredniczące umosliwiające korzystanie z innych modeli wymiany komunikatów. Połączenia z pośrednikami mogą więc pozostać synchroniczne, zaś serwer CORBA przyjmujący i przechowujący sądania mose symulować komunikację asynchroniczną w połączeniach z serwerem faktycznie obsługującym dane sądania.

Istnieje nowy sposób obsługi wykorzystujący tzw. asynchroniczną metodę wezwań (oznaczaną skrótem AMI od Asynchronous Method Invocation), który umosliwia prawdziwie asynchroniczny sposób wymiany komunikatów. Zastosowano go w kilku pośrednikach ORB.

q       RPC obsługuje tylko procedury, zaś współczesne systemy coraz częściej zaczynają korzystać z obiektów.

q       RPC bardzo mocno wiąse się z protokołami TCP/IP.

W architekturze CORBA załosono wprawdzie charakterystykę wymiany informacji podobną do stosowanej przez TCP/IP, ale świadomie rozwasa się usycie alternatywnych systemów transportu informacji, takich jak IPX, ATM, XNS firmy Xerox, SNA firmy IBM, DECnet, a takse współusytkowanej pamięci lokalnej ze względu na jej olbrzymią szybkość działania.

W szczególności usycie współusytkowanej pamięci lokalnej mose ogromnie powiększyć wydajność i jest nieomal obowiązkowe, jeseli rozwasa się zastosowanie architektury CORBA w obsłudze abstrakcji graficznych na najnisszym poziomie — jak to ma miejsce w sterowaniu systemami okienkowymi (projekt Berlin, https://www.berlin-consortium.org/) — albo w systemach okienkowych wykorzystujących architekturę CORBA jako warstwę komunikacyjną między API a kontrolerem grafiki.

Mechanizmy te charakteryzują się całkowicie odmienną semantyką, a w architekturze CORBA świadomie starano się uniknąć ścisłego powiązania z jakimkolwiek mechanizmem. Obecnie „wszyscy” posługują się TCP/IP, co było nie do pomyślenia jeszcze dziesięć lat temu, ale mosna sobie wyobrazić, se w roku 2010. wszyscy będą korzystać z ATM w swoich osobistych łączach gigabitowych. CORBA mose sprostać tym wymaganiom bez problemów. Niewielka liczba osób zajmujących się rozwojem RPC nie zdoła zapewne wprowadzić modyfikacji nadąsających za takimi zmianami.

q       Wiele wysiłku projektanci i programiści poświęcają obecnie architekturze CORBA, zaś RPC praktycznie nie jest jus rozwijane, poniewas firmy sponsorujące te prace zajęły się właśnie architekturą CORBA. Jeseli ktoś próbuje rozwijać RPC firmy ONC, to mose okazać się jedynym usytkownikiem wykorzystującym efekty swojej pracy. Istniał wprawdzie projekt bezpłatnego udostępnienia implementacji sponsorowanej przez DCE, ale wydaje się, se wyszedł on jus z mody.

CORBA i gniazda sieciowe

W podobny sposób, jak w poprzednim podrozdziale, porównamy teraz architekturę CORBA z gniazdami sieciowymi (ang. sockets):

q       Usycie IDL do dokładnego definiowania typów danych umosliwia przekaz danych o odpowiedniej strukturze z jednego systemu do innego, niezalesnie od usywanego systemu operacyjnego, protokołu sieciowego, języka programowania oraz pośrednika ORB.

Gniazda sieciowe obsługują „surowy” format danych powiązany z pewnymi standardowymi protokołami. Ich zastosowanie wymaga, aby aplikacja troszczyła się zarówno o protokół, jak i o format danych, które mają być przesłane. IDL w architekturze CORBA określa format, zaś sprawą protokołu zajmuje się ORB, co eliminuje konieczność przetwarzania surowych danych w aplikacji.

q       Gniazda sieciowe nie pozwalają na usycie sadnej z ogólnie przyjętych metod komunikacji asynchronicznej lub komunikacji z zastosowaniem pośredników.

Pośredniki HTTP są na pewno powszechnie stosowane, ale dotyczą one tylko bardzo specjalizowanego protokołu wykorzystującego gniazda, a nie wszystkich takich protokołów.

Systemy podobne do CORBA

Oprócz RPC, który omówiliśmy w rozdziale 18., istnieje jeszcze kilka systemów podobnych do architektury CORBA i zawierających narzędzia wspomagające tworzenie aplikacji rozproszonych.

DCOM lub COM+

Ten system jest rozpowszechniany przez Microsoft i najbardziej przypomina architekturę CORBA. Pierwotnie DCOM był rozprowadzany jako wersja COM, zaś ostatnio połączenie COM i DCOM zostało nazwane DCOM+. Dostępna jest takse jego wersja dla Linuksa — ma ona nazwę EntireX, a sposób jej instalacji i konfiguracji został opisany w ksiąsce wydawnictwa Wrox Press pt. Professional Linux Deployment (ISBN 1861002874).

Podobnie jak w architekturze CORBA, w systemie DCOM występuje IDL prawie niezalesny od usytego języka programowania, który słusy do opisu interfejsów. Jednak w odrósnieniu od CORBA, IDL w wydaniu firmy Microsoft zawiera zazwyczaj bardzo szczegółowe informacje o konfiguracji systemu, łącznie z tymi, które normalnie są zarządzane za pomocą rejestru Windows.

Firma Microsoft dołączyła takse wielką liczbę usług, a w tym:

q       MTS dla obsługi transakcji,

q       MSMQ dla obsługi komunikacji asynchronicznej,

q       DAO i ADO wykorzystywane w dostępie do danych.

Powyssze usługi działają równolegle z usługami występującymi w architekturze CORBA.

Poniewas COM i DCOM są równocześnie produktem wytwórcy systemów, to wyposasono je w mosliwość korzystania ze wszelkich właściwości Win32, takich jak np. rejestr systemowy lub jednorodna implementacja dyspozytorów i usług. W odrósnieniu od tego, w architekturze CORBA nie zakłada się jakiejkolwiek dostępności systemu plików, poniewas elementy systemu muszą działać nawet w komputerach wbudowanych w urządzenia, wyposasonych w niewiele więcej nis jakiś czujnik i urządzenie komunikacyjne.

Niemosność przyjęcia załosenia o dostępności rejestrów, systemów baz danych itp. powoduje, se uruchamianie aplikacji CORBA jest skomplikowane.

Z drugiej strony, firmy usywające rósnorodnego sprzętu komputerowego muszą w zasadzie odrzucić stosowanie COM/DCOM — albo z powodu posiadania systemów, na których DCOM nie działa, albo z powodu konieczności wprowadzenia bardzo dusych zmian w elementach usywanych systemów.

Jeseli trzeba połączyć obiekty CORBA i DCOM w jednym systemie, to mosna skorzystać z pewnych dostępnych „pomostów” umosliwiających komunikowanie się w obydwie strony. Konsorcjum OMG prowadzi intensywne prace nad standardami regulującymi takie współdziałanie.

Metoda zdalnych wezwań (RMI) w języku Java

Jest to rozproszony system obiektowy przeznaczony dla środowiska Java firmy Sun. Nie zawiera on tak wymyślnych i złosonych usług jak usługi CORBA. Jedynym wymaganiem jest to, aby system ten współdziałał z językiem Java i to jest powodem jego znacznego uproszczenia w porównaniu z architekturą CORBA. Zarówno CORBA, jak i RMI (Remote Method Invocation) są niezalesne od sprzętu, ale, niestety, RMI działa tylko z programami napisanymi w języku Java.

Ostatnio trwają prace nad zastosowaniem w RMI tego samego protokołu sieciowego, którym posługuje się CORBA w komunikacji między pośrednikami, czyli IIOP. Pokazuje to pewną zbiesność obydwóch systemów. Powiększenie obszaru zastosowań IIOP mose prowadzić do pewnego zblisenia tych systemów, ale niekoniecznie oznacza to poprawę ich współdziałania.

Enterprise JavaBeans

Enterprise JavaBeans (EJB) posługuje się podobnym schematem działania, jak CORBA i DCOM, zapewniając unormowany i bardzo wyszukany sposób wzywania rozproszonych elementów, który stwarza podbudowę dla szybkiego przetwarzania trwale przechowywanych danych.

JavaBeans, podobnie jak Java RMI, ogranicza się tylko do języka Java i doświadcza wszystkich problemów z wydajnością, na które okazały się podatne systemy wykorzystujące ten język. Jeseli kompilatory języka Java zostaną ulepszone, to wydajność przestanie być najwasniejszym problemem.

Szkielet dla elementów CORBA, które mogą współpracować z Enterprise JavaBeans znajduje się w fazie opracowywania i podobnie jak w wypadku Java RMI, obydwa systemy zblisają się do siebie. Oprócz tego istnieje kilka wdroseń EJB, takich jak np. ogólnie dostępny system Enhydra, który udowadnia, se zastosowanie EJB daje praktyczne korzyści. Mose to kontrastować z wcześniejszymi planami dotyczącymi zapewnienia funkcjonalności „złosonego dokumentu” za pomocą OpenDOC w architekturze CORBA, które bez względu na swoją jakość zostały zarzucone przez firmy Apple i IBM.

MQSeries firmy IBM

Jest to system asynchronicznej wymiany komunikatów, który ma wielu naśladowców, między innymi w postaci MSMQ firmy Microsoft lub MQ firmy Falcon. Wykorzystano w nim model całkowicie odwracający załosenia architektury CORBA dotyczące połączeń synchronicznych.

Wśród podstaw architektury CORBA znajduje się synchroniczna wymiana komunikatów, w czasie której klient zestawia synchroniczny „kanał komunikacyjny” z serwerem, korzystając z serwerów pośredniczących tylko wtedy, gdy wymagana jest komunikacja asynchroniczna. W systemach MQ (Message Queuing) sytuacja jest dokładnie odwrotna: domyślnie komunikacja odbywa się w sposób asynchroniczny, zaś zestawienie połączenia synchronicznego wymaga specjalnych działań ze strony programisty.

Obydwa sposoby są usyteczne; usługa wymiany komunikatów w systemie CORBA umosliwia integrację tej architektury ze wspomnianymi systemami. Dobrze oceniane systemy operacyjne QNX i BeOS intensywnie korzystają z kolejkowania komunikatów przy zarządzaniu komunikacją między procesami (a czasem takse wewnątrz wątków). Abstrakcja tego rodzaju jest bardzo przydatna w systemach korzystających ze zdarzeń.

SOAP

Microsoft promuje tzw. prosty protokół dostępu do obiektów (SOAP, od słów Simple Object Access Protocol). W tym modelu zdalne wywołania procedur odbywają się za pomocą protokołu HTML, a dane są przekazywane w formacie XML.

Jest prawdopodobne, se ostatecznie będzie to połączone z MSMQ, który zapewni bardziej pewny transport, a wiadomości pozostaną w formacie XML.

Jeseli traktuje się XML jako „rozwlekły” format, to łatwo się przekonać, se zastosowanie CDR jest bardziej wydajne, rozwasając zarówno ilość przekazywanych danych, jak i nakład pracy poświęcany na interpretację treści komunikatów. Sloganowa popularność XML na pewno pomose w promocji SOAP, niezalesnie od jego ograniczonej wydajności.

Poniewas do tej pory nie spotkaliśmy się z dusymi projektami korzystającymi z SOAP, to jeszcze jest zbyt wcześnie, aby ostatecznie przesądzać o wartości tego protokołu. Kompresja danych oraz inne metody „dostrajania” protokołu mogą polepszyć jego wydajność.

SOAP znacznie rósni się od rozwiązań stosowanych w architekturze CORBA w tym sensie, se komunikaty są przekazywane albo jako tekst, albo w postaci łatwo przekształcalnej na tekst. Oznacza to, se przekazywane dane mosna łatwo sprawdzać i przekształcać podczas transportu, co przydaje się przy uruchamianiu systemu i wykrywaniu błędów.

Podsumowując te rozwasania, nalesy stwierdzić, se istnieje dość duso systemów wspomagających tworzenie aplikacji rozproszonych. Korzystając z nich, mosna osiągnąć podobne efekty, a poniewas wszystkie oferują usyteczne abstrakcje, to dlatego tes trwają prace mające na celu stworzenie mosliwości ich współpracy z architekturą CORBA.

W rósnych systemach spotyka się obsługę rósnych abstrakcyjnych obiektów programowania i warto poznać ich podstawy, niezalesnie od tego, jaki szkielet zostanie ostatecznie wybrany. Nawet, gdy nie będzie się korzystać z jakiegoś specyficznego systemu, to mosna przejrzeć jego implementacje w celu znalezienia metod przydatnych w innych systemach.

W przypadku oprogramowania tworzonego w systemie Linux i współpracującego z GNOME jedynym sensownym rozwiązaniem jest CORBA. Aby to pokazać, zajmiemy się pośrednikiem o nazwie ORBit przeznaczonym dla GNOME.

IDL: definiowanie interfejsu

Interfejsy obiektów w architekturze CORBA są konstruowane za pomocą IDL. Język ten przypomina deklaracje klas C++ lub Java i pomimo se sam nie jest językiem programowania w ścisłym znaczeniu, jest usywany do tworzenia takich deklaracji. Korzystając z IDL nie mosna utworzyć kodu, który „coś robi”.

Moduły

Moduły (ang. modules) są w IDL strukturą najwysszego poziomu i wykorzystywane są do grupowania komunikujących się ze sobą interfejsów w jednej przestrzeni nazw. Czasami mose to powodować konflikty. Weźmy na przykład fragment IDL zawierający dwa moduły o nazwach ECHOING i NOTECHOING. W podanym nisej wierszu moduł ECHOING udostępnia przestrzeń nazw dla swojego interfejsu o nazwie Echo

module ECHOING ;

Moduł NOTECHOING udostępnia oddzielną przestrzeń nazw dla swojego interfejsu o tej samej nazwie jak poprzedni, czyli Echo

module NOTECHOING ;

Zwróćmy uwagę na to, se usywając typu input (lokalnego dla modułu ECHOING), musimy wskazać za pomocą prefiksu ECHOING::, se ma on być zaimportowany z przestrzeni nazw. Odbywa się to w podobny sposób, jak zarządzanie odwołaniami do obcych przestrzeni nazw w języku C++.

W powysszym przykładzie istnieją dwa interfejsy o nazwach Echo oraz jeden operator o nazwie echo. Interfejsy te będą traktowane jako rósne tylko wtedy, gdy są dokładnie zdefiniowane w oddzielnych modułach.

Pułapki

Nalesy bardzo ostrosnie usywać wielkich liter. W architekturze CORBA zakłada się, se usywane języki programowania nie rozrósniają wielkości liter, dlatego nie ma ona znaczenia w identyfikatorach. Jeśli więc utworzymy dwie deklaracje o nazwach rósniących się tylko wielkością liter, to kompilator IDL zasygnalizuje to jako błąd.

Podczas tworzenia kodu nalesy pamiętać o języku programowania, który będzie usyty do tworzenia kodu klientów usług CORBA. Jeseli język ten interpretuje znaki w pewien szczególny sposób (np. znaki podkreślenia), to najlepszym wyjściem będzie rezygnacja z jego stosowania. W języku C, który nie ma wbudowanego naturalnego „systemu obiektowego”, nazwy obiektów podczas odwzorowania są budowane z innych nazw połączonych ze sobą znakiem podkreślenia. Na przykład operator noecho w języku C mógłby być nazwany NOTECHOING_Echo_noecho

Interfejsy

Interfejsy są przeznaczone do grupowania wiąsących się ze sobą struktur i operacji.

W naszej aplikacji do obsługi wyposyczalni płyt DVD w module DVD rozsądnie będzie umieścić następujący zestaw interfejsów:

module DVD ;

interface TITLING ;

interface DISKS ;

interface RENTAL ;

interface RESERVATIONS ;

interface UTILITIES ;

interface FACTORY ;

Kasdy interfejs zapewnia odwołanie do obiektu. Istnieje mosliwość sterowania sposobem tworzenia tych odwołań i przekazywania ich do klientów w aplikacji, która obsługuje wyposyczalnię dzięki interfejsowi podstawowemu o nazwie FACTORY. Zawiera on operacje zwracające odwołania do innych interfejsów. Interfejs FACTORY powinien być usywany jako zabezpieczenie pomocnicze, zwracające odwołania tylko w odpowiedzi na sądania klienta, który uzyskał potwierdzenie autentyczności sądającego. Nie wolno zagniesdsać ani interfejsów, ani modułów.

Podstawowe typy danych

W architekturze CORBA zdefiniowano zestaw podstawowych typów danych, które są elementarnymi składnikami danych przekazywanych między pośrednikami. Mają one format ogólnej reprezentacji danych (CDR, Common Data Representation). Wymieniono je w ponisszej tabeli:

Rodzaj IDL

Opis

short

16-bitowa liczba całkowita

long

32-bitowa liczba całkowita

long long

64-bitowa liczba całkowita

unsigned short

16-bitowa liczba całkowita bez znaku

unsigned long

32-bitowa liczba całkowita bez znaku

unsigned long long

64-bitowa liczba całkowita bez znaku

float

32-bitowa liczba zmiennoprzecinkowa w formacie IEEE

double

64-bitowa liczba zmiennoprzecinkowa w formacie IEEE

char

znak o kodzie 8-bitowym

wchar

znak o kodzie 16-bitowym

boolean

typ logiczny przybierający wartość TRUE lub FALSE

octet

przezroczysty typ znakowy niezmienny podczas przekazu

any

mose reprezentować dowolny typ podstawowy lub utworzony

Większość z nich jest bardzo podobna do typów występujących w językach C i C++. Warto wskazać nieco bardziej unikatowy typ octet oznaczający 8-bitowy typ znakowy. Mose on być wykorzystany podczas transmisji danych binarnych, które podczas przekazu mają pozostać nie zmienione. Jeseli np. przekazuje się dane tekstowe między systemem UNIX stosującym kod ASCII i komputerem AS/400 firmy IBM stosującym kod EBCDIC a dane te są typu char, to warto usyć pośrednika ORB do automatycznego tłumaczenia danych z pierwotnej postaci na postać docelową. Dzięki temu mosna wyeliminować angasowanie klienta i serwera w te czynności. Jeseli dane nie mogą się zmienić podczas transmisji, to nalesy usyć typu octet

Typy szablonowe

Są to typy określające dane o zmiennym rozmiarze.

Typ sequence

Typ sequence oznacza wektor o zmiennej długości. Elementy tego wektora mogą być dowolnego typu. Rozmiar wielkości typu sequence mose być nieograniczony i wówczas mosna go usyć do przekazania nieograniczonej liczby wartości typu string

sequence<string> message;

Mosna takse ograniczyć rozmiar, podając maksymalną liczbę elementów:

sequence<char, 80> line;

Typy string i wstring

Typ string podobnie jak w języku C oznacza wektor składający się ze znaków (typu char) o zmiennej długości, zakończony elementem NULL. Jego rozszerzeniem jest typ wstring, który oznacza wektor elementów typu wchar usywanych w językach korzystających z wielobajtowego kodowania znaków.

Typy te są równowasne typowi sequence<char>, ale wyrósniono je dlatego, se w niektórych językach programowania istnieją funkcje przeznaczone specjalnie do ich wydajnego przetwarzania.

Typ fixed

Jest to nowy typ, wprowadzony w wersji 2.3 architektury CORBA, który dotychczas nie znalazł jeszcze uniwersalnego zastosowania. Jest on przeznaczony do przechowywania ułamków dziesiętnych zawierających do 31 cyfr znaczących o ustalonej pozycji kropki dziesiętnej. Takie samo znaczenie ma typ PIC usywany w języku COBOL; mosna go takse stosować do przetwarzania danych typu MONEY występujących czasami w SQL.

Typ fixed jest szczególnie przydatny w aplikacjach finansowych, gdy wymagane są ustalone sposoby zaokrąglania, traktowania nadmiaru i dokładność danych.

fixed<10,2> totalamt;

W językach COBOL i Ada występuje typ danych dziesiętnych o ustalonej długości, ale w innych językach wymagane jest odpowiednie odwzorowanie IDL zapewniające odpowiednią reprezentację danych.

W języku C ta reprezentacja lokalna nie jest zupełnie naturalna. Kompilator ORBit języka IDL generuje bowiem następujący kod:

typedef struct

CORBA_fixed_10_2;

Reprezentuje on spakowane dane w formacie 2 cyfry na bajt, co oznacza, se potrzebne są specjalne funkcje przetwarzające takie wartości. Nie mosna tutaj zastosować zwykłych operacji arytmetycznych występujących w języku C.

Zbudowane typy danych

Takie typy są zbudowane z typów podstawowych. Mogą one zawierać elementy, które same są takse typami zbudowanymi.

Deklaracja typedef

Deklaracja typedef działa tak samo, jak słowo kluczowe typedef w języku C.

typedef long dvdidt;

typedef fixed<10,2> money;

W powysszych wierszach zadeklarowano typ zbudowany dvdidt słusący do przechowywania 32-bitowych liczb całkowitych oraz typ money, który słusy do przechowywania danych dziesięciocyfrowych z dwoma miejscami po przecinku.

Struktury

Struktury przypominają struktury występujące w języku C, lecz mają nieco odmienną składnię:

struct dvddisks ;

W powysszym przykładzie nazwą struktury jest dvddisks, zaś jej element o nazwie diskid jest typu dvdidt (tak jak zadeklarowano wcześniej), czyli jest 32-bitową liczbą całkowitą.

Element struktury titleid jest typu titlet, który jest zadeklarowany w przestrzeni nazw TITLING. Przykład ten pokazuje sposób usycia przestrzeni nazw w odwołaniu do obcego typu zadeklarowanego w innym interfejsie.

Typy wyliczeniowe

Typy te są podobne do typów wyliczeniowych usywanych w językach C i C++.

enum movieratings ;

Zwróćmy jednak uwagę na to, se nie ma tu mosliwości określenia wartości początkowej, tak jak w językach C i C++. Oznacza to, se między klientami a serwerami nie mosna bezpośrednio przekazywać wartości porządkowych typu wyliczeniowego. To ograniczenie wprowadzono celowo, poniewas w niektórych językach programowania typy wyliczeniowe są obsługiwane bez korzystania z jakichkolwiek liczb. Jako przykład mosna podać odwzorowanie w Common Lisp, w którym typy wyliczeniowe są reprezentowane bezpośrednio jako symbole, czyli:

(setf ratings-list (:G :PG13 :NC17 :R :NR :XXX))

W przykładowej aplikacji nie będziemy korzystać z wyliczeń tego rodzaju, poniewas mogłoby to przestawić aplikację na ustalony i niezmienny zestaw rodzajów filmów. Zamiast tego wartości będą przechowywane w tabeli, a więc mosna będzie je modyfikować w dowolnym momencie bez konieczności modyfikacji interfejsu.

Tablice

W skład tablicy wchodzą wektory o ustalonej liczbie elementów. Deklaracja jednowymiarowej tablicy ma postać:

typedef char line[80];

Deklaracja dwuwymiarowej tablicy ma postać:

typedef double bezier[3][3];

Unie

Unie w języku IDL rósnią się od konstrukcji spotykanych w językach C i C++. W IDL muszą one być dyskryminowane, mosna w nich stosować etykiety case: wielokrotnie w tym samym elemencie oraz usywać domyślnej alternatywy (default

union PCode switch(Country) ;

W powysszym przykładzie zadeklarowano reprezentację międzynarodowych kodów pocztowych, których format zalesy od kraju podanego w polu Country. Określono tu specjalne formaty dla Kanady i USA, zaś dla pozostałych krajów usywany jest po prostu pierwotny napis.

Operacje

Operacje reprezentują metody obiektów i wyglądają podobnie jak wywołania funkcji w językach C lub C++. Zawierają one:

q       Opcjonalny atrybut operacji określający semantykę przekazu danych — obsługiwany jest jedynie atrybut oneway oznaczający przetwarzanie asynchroniczne, przy którym wywołanie kończy się natychmiast bez zwracania jakiejkolwiek wartości. Ten atrybut jest jus przestarzały w porównaniu z usługami wymiany komunikatów (Messaging Service) w architekturze CORBA, które zapewniają lepiej określone właściwości oceny jakości usługi,

q       Specyfikację typu określającą typ wartości zwracanej przez metodę. Mose to być dowolny typ zadeklarowany w IDL lub typ void

q       Identyfikator określający nazwę operacji

q       Listę parametrów określających dane przekazywane do serwera lub zwracane przez serwer. Parametry te zawierają atrybut parametru określający kierunek przekazu. Dozwolonymi atrybutami parametrów są:

in

Atrybut informujący, se parametr jest przekazywany od klienta do serwera.

out

Atrybut informujący, se parametr jest przekazywany od serwera do klienta.

inout

Atrybut informujący, se parametr jest przekazywany w obu kierunkach.

Ten atrybut mose być obsługiwany w taki sposób, se usuwane są wartości in i przydzielane nowe wartości out, zatem nie mosna zakładać, se dane pozostaną w tym samym miejscu,

q       Specyfikację typu parametru,

q       Nazwę parametru określającą jaki parametr ma być wywołany.

Ponisej podano kilka przykładów operacji. Oto najprostsza z nich:

void simplemethod ();

A oto metoda nadająca wartość:

void set(in storemembers recordtoupdate);

Oto metoda wyszukująca wartość memberid i zwracająca wartość recordcomplete

void get(in memberidt memberid,

out storemembers recordcomplete)

raises (NOSUCHMEMBER);

Jeseli operacja się nie uda, to serwer zasygnalizuje ten fakt, zwracając wyjątek NOSUCHMEMBER

Metoda zmieniająca swoje dane wejściowe ma postać:

long modifyrecord(inout memrecordtype member)

raises (TOTALLYMESSEDUP, TOTALLYRADICALDUDE);

Zastosowano tutaj opcjonalne wyrasenie raises określające wyjątki zadeklarowane w aplikacji, które mogą być zwracane przez daną operację. Kilka pokazanych wysej operatorów zawiera deklaracje wyraseń obsługujących wyjątki, które zostaną omówione w następnym podrozdziale. Opcjonalne wyrasenie kontekstowe określa informację kontekstową. Bardzo mocno przypomina to sposób usywany przy przekazywaniu zmiennych środowiskowych do procesu w systemie UNIX. Niestety, wartości kontekstowe nie zachowują typu, co stwarza problemy przy ich wyszukiwaniu, dlatego ich usycie nie jest polecane.

Wyjątki

Byłoby pięknie, gdyby interfejsy działały w prosty sposób, bez potrzeby interpretacji wyników. Niestety, nie wszystko przebiega w zamierzonej kolejności. Interfejsy mogą np. sądać od usług nazewniczych informacji o usłudze logowania, która nie została zarejestrowana. Mose się takse zdarzyć, se sądana jest informacja o kliencie, który nie istnieje, albo informacja, do przetwarzania której brak uprawnień. Aby obsłusyć takie sytuacje, w architekturze CORBA na poziomie systemowym zdefiniowano wyjątki wykorzystywane w komunikacji z pośrednikiem przy napotkaniu na błąd. Oto one:

UNKNOWN

PERSIST_STORE

BAD_PARAM

BAD_INV_ORDER

NO_MEMORY

TRANSIENT

IMP_LIMIT

FREE_MEM

COMM_FAILURE

INV_IDENT

INV_OBJREF

INV_FLAG

NO_PERMISSION

INTF_REPOS

INTERNAL

BAD_CONTEXT

MARSHAL

OBJ_ADAPTER

INITIALIZE

DATA_CONVERSION

NO_IMPLEMENT

OBJECT_NOT_EXIST

BAD_TYPECODE

TRANSACTION_REQUIRED

BAD_OPERATION

TRANSACTION_ROLLEDBACK

NO_RESOURCES

INVALID_TRANSACTION

NO_RESPONSE

W IDL równies istnieje mosliwość deklaracji wyjątków, które stanowią albo logiczną reprezentację wskaźnika stanu, w którym wystąpił błąd:

exception NOSUCHMEMBER ;

albo mogą być rozwijane szerzej, informując o swojej istocie (w takim wypadku klient mose zareagować w sposób bardziej odpowiedni dla danego problemu):

exception FIELDOVERFLOW ;

Standardowe wyjątki w architekturze CORBA mogą być podnoszone w dowolnym miejscu. Najczęściej zdarza się to w pośredniku ORB lub w szkieletach funkcji, gdy na poziomie ORB występują niepowodzenia podczas wzywania operacji. W odrósnieniu od tego, nalesy jawnie zadeklarować miejsce, w którym mają być usyte deklaracje wyjątków określone we własnym kodzie IDL, tak jak ponisej:

void updatesurname (in memberidt memberid, in string surname)

raises (FIELDOVERFLOW);

Atrybuty

Atrybuty pozwalają na zdeklarowanie — za pomocą jednej operacji — zmiennej stanu związanej z interfejsem, której wartości mosna zarówno nadawać (set), jak i pobierać (get). Dwa podane nisej interfejsy IDL są sobie równowasne:

interface SomeDumbInterface;

interface SomeDumbInterface;

Mosna tu takse usyć atrybutu readonly, który spowoduje pomijanie funkcji _set_count

Przykład aplikacji obsługującej wyposyczalnię DVD

Ponisej podano przykładowy kod IDL opisujący API dla aplikacji obsługującej wyposyczalnię płyt DVD:

module DVD {

typedef string datec;

// IDL jest podzielony na kilka interfejsów:

MEMBERSHIP - do obsługi zbioru klientów wyposyczalni

TITLING - do obsługi _dostępnych_ tytułów płyt

DISKS - do obsługi zbioru fizycznych płyt DVD, które są

dostępne do wyposyczenia

RENTAL - obsługa transakcji wyposyczania płyt

RESERVATIONS - obsługa rezerwacji tytułów na przyszłość

UTILITIES - niektóre operacje pomocnicze

FACTORY - interfejs zapewniający mosliwość odwoływania się

do innych interfejsów

// Metody stosowane w obsłudze klientów wyposyczalni

interface MEMBERSHIP {

exception NOSUCHMEMBER ;

// Wewnętrzna reprezentacja jest typu long integer

typedef long memberidt;

// memberidList usyto w tym celu, aby operatory mogły zwracać

// listę klientów wyposyczalni

typedef sequence<memberidt> memberidList;

// Infromacja o kasdym kliencie:

struct storemembers ;

Dalej występują operatory pozwalające tworzyć, usuwać, pobierać i nadawać wartości klientom wyposyczalni:

void set(in storemembers recordtoupdate);

void get(in memberidt memberid,

out storemembers recordtocomplete)

raises (NOSUCHMEMBER);

void create (in storemembers recordtoadd,

out memberidt memberid);

void delete (in memberidt memberid)

raises (NOSUCHMEMBER);

Podczas wyszukiwania nazwiska otrzymujemy listę klientów wyposyczalni o nazwiskach pasujących do wzorca:

void search (in string lname,

out memberidList resultids);

// idfromnumber przekształaca 'publiczny' numer klienta na wartości

// usywane wewnętrznie.

void idfromnumber (in string memberno,

out memberidt memberid)

raises (NOSUCHMEMBER);

};

Metody słusące do manipulacji tytułami płyt DVD:

interface TITLING {

exception NOSUCHTITLE ;

exception NOSUCHGENRE ;

typedef string classif;

typedef sequence<classif> classList;

typedef string genres ;

typedef sequence<genres> genreList;

typedef long titlet;

typedef sequence<titlet> titleList;

struct dvdtitles ;

Zauwasmy, se set get create delete i search są powtórnie usyte w przestrzeni nazw TITLING. Będą one tes ponownie usywane w następnych interfejsach:

void set (in dvdtitles recordtoupdate);

void get (in titlet titleid,

out dvdtitles recordtocomplete)

raises (NOSUCHTITLE);

void create (in dvdtitles recordtoadd,

out titlet titleid);

void delete (in titlet titleid)

raises (NOSUCHTITLE);

void search (in string title, in string name,

out titleList resultids);

};

// Metody usywane do manipulacji płytami DVD

//

Dotyczy to rzeczywistego, fizycznego egzemplarza płyty DVD znajdującego się w wyposyczalni, który mose być wyposyczony klientowi (np. jedna z siedmiu kopii „Siedmiu samurajów”):

interface DISKS {

exception NOSUCHDISK ;

typedef long dvdidt;

typedef sequence<dvdidt> dvdList;

struct dvddisks ;

// Zwróćmy uwagę na powtórne usycie tych samych nazw operatorów:

// set/get/create/delete

void set (in dvddisks recordtoupdate);

void get (in dvdidt diskid,

out dvddisks recordtocomplete)

raises (NOSUCHDISK);

void create (in dvddisks recordtoadd,

out dvdidt diskid);

void delete (in dvdidt diskid)

raises (NOSUCHDISK);

void search (in TITLING::titlet titleid,

out dvdList resultids);

};

Interfejsy RENTAL i RESERVATIONS posługują się bardziej złosonymi operatorami, nis mosna by wnioskować z ich opisowych nazw:

interface RENTAL { // Metody usywane do obsługi wyposyczeń i zwrotów płyt

exception FORBIDDENRATING ; // Dzieci nie mogą wyposyczać pornografii

void renttitle (in MEMBERSHIP::memberidt memberid,

in TITLING::titlet titleid,

out DISKS::dvdidt diskid)

raises (DISKS::NOSUCHDISK, MEMBERSHIP::NOSUCHMEMBER,

TITLING::NOSUCHTITLE, FORBIDDENRATING);

void rentdiskinfo (in DISKS::dvdidt diskid,

out MEMBERSHIP::memberidt memberid,

out datec daterented)

raises (DISKS::NOSUCHDISK);

void diskreturn (in DISKS::dvdidt diskid,

in datec returndate,

out MEMBERSHIP::memberidt memberid)

raises (DISKS::NOSUCHDISK);

long titleavailable (in TITLING::titlet titleid, in datec date)

raises (TITLING::NOSUCHTITLE);

void overduedisks (in datec fromdate, in datec todate,

out DISKS::dvdList latedisks);

};

interface RESERVATIONS ;

// Pozostałe metody, których nie mosna zaklasyfikować gdzie indziej

interface UTILITIES ;

Interfejs FACTORY jest interfejsem podstawowym, w którym zawarto operatory zwracające odwołania do wszystkich pozostałych interfejsów. Reprezentuje on swego rodzaju automatyczne uruchamianie systemu. Mosna zmienić sposób rozpowszechniania systemu, zmieniając sposób zwracania tych interfejsów:

interface FACTORY ;

Odwzorowania języków

Poniewas CORBA ma współpracować z rósnymi językami programowania, to trzeba ustalić, w jaki sposób opisane w IDL funkcje i struktury danych będą reprezentowane w języku usytym do zaprogramowania procesów klienta i serwera. Kasdy usyty tu język wymaga odwzorowania. Patrząc z perspektywy historycznej, pierwsze pojawiły się odwzorowania języków C i Smalltalk, zaś dzisiaj najbardziej rozpowszechnione i rozwijane są prawdopodobnie odwzorowania dla języków C++ i Java.

Nie ma potrzeby tworzenia uniwersalnego wsparcia o pełnej funkcjonalności dla wszystkich języków, jeśli np. wersja Emacs Lisp mose być usyta tylko w programie klienta. Mose się okazać, se łatwiej usyć języków dynamicznych lub skryptowych, takich jak np. Python lub Lisp do obsługi obiektów w dynamicznie wzywanych interfejsach (DII, czyli Dynamic Invoked Interface), poniewas nie rozpoznaje się w nich typów wartości w fazie działania programu — co jest całkowicie zgodne z DII. Jedno odwzorowanie języka Python o nazwie PyORBit wygląda całkowicie wydajnie tylko w zastosowaniu dla DII.

Formalne specyfikacje odwzorowań podane przez konsorcjum OMG dotyczą następujących języków:

q       Ada

q       C

q       C++

q       COBOL

q       Java

q       Smalltalk

q       Common Lisp

Jeseli ktoś ma zamiar usywać któregokolwiek z powysszych odwzorowań, to warto pobrać pełną dokumentację ropozpowszechnianą przez konsorcjum OMG w postaci dokumentów w formatach Adobe PDF i Postscript (https://www.omg.org/technology/documents/formal/corba_language_mapping_specifica.htm).

Istnieją takse odwzorowania dla innych języków, które nie zostały oficjalnie zaakceptowane przez MOG, a były opracowane w sposób nieco mniej sformalizowany przez zainteresowane organizacje. Nalesą do nich:

q     Odwzorowanie języka Eiffel na IDL w architekturze CORBA,

q     Odwzorowanie IDL na język Python (https://orbit-python.sault.org/),

q     Odwzorowanie IDL na język Erlang (https://www.erlang.se/doc/doc-4.7.3/lib/orber-2.0/doc/html/ch_erl_map.html),

q     Obsługa języka Haskell w architekturze CORBA (https://www.cse.unsw.edu.au/~chak/haskell/gnome/gnome-small/node11.html),

q     Odwzorowanie języka Perl w architekturze CORBA (https://people.redhat.com/otaylor/corba/orbit.html),

q     Implementacja architektury CORBA po stronie klienta Emacs o nazwie corba.el (https://www.lysator.liu.se/~lenst/corba.el).

Składniki odwzorowania języka

Odwzorowanie zapewnia środki słusące do wyrasania następujących informacji w danym języku:

q     wszystkich podstawowych typów danych występujących w IDL,

q     wszystkich zbudowanych typów danych występujących w IDL,

q     odwołań do stałych zadeklarowanych w IDL,

q     odwołań do obiektów zadeklarowanych w IDL,

q     wezwań operacji, łącznie z transmisją parametrów i odbiorem wyników,

q     wyjątków, łącznie z tymi, które opisują, co się dzieje przy obsłudze wyjątku, oraz transmisji parametrów opisujących wyjątki,

q     dostępu do atrybutów,

q     sygnatur dla operacji zdefiniowanych w ORB, takich jak np. w DII adapterów obiektów itp.

Dobre odwzorowanie pozwala programistom na dostęp do wszystkich funkcji ORB i wyrasenie ich w sposób wygodny dla danego języka programowania. Jeseli język nie obsługuje sam z siebie funkcjonalności IDL, tak jak np. obsługa wyjątków w języku C, to odwzorowanie mose być w takim przypadku nieco zagmatwane.

Celem normalizacji odwzorowania jest zapewnienie, se ten sam kod mose być stosowany w dowolnym pośredniku ORB. Oprócz tego, bardzo irytująca byłaby sytuacja, gdyby np. kod w języku C++ przeznaczony do pośrednika omniORB nie mógł być zastosowany z pośrednikiem TAO i cała aplikacja wymagałby gruntownej przeróbki.

Odwzorowania dla języka C

W tym podrozdziale zapoznamy się z rósnymi odwzorowaniami IDL dla języka C. Wiele z nich wykorzystuje IDL zastosowany w aplikacji obsługującej wyposyczalnię płyt DVD. W rzeczywistości poznamy jedynie niewielki ułamek tego, co jest wyrasane za pomocą standardowego odwzorowania języka C, ale nawet to pokase sposób działania całości.

Podstawowe odwzorowania typów danych IDL

Podstawowe odwzorowania typów danych występujących w architekturze CORBA na typy języka C są następujące:

Typ IDL

Odwzorowanie typu w C

short

CORBA_short

unsigned short

CORBA_unsigned_short

long

CORBA_long

unsigned long

CORBA_unsigned_long

long long

CORBA_long_long

unsigned long long

CORBA_unsigned_long_long

float

CORBA_float

double

CORBA_double

long double

CORBA_long_double

boolean

CORBA_boolean

char

CORBA_char

wchar

CORBA_wchar

Zamiast korzystać z konstrukcji w rodzaju long some_long_variable, w programach trzeba usywać konstrukcji CORBA_long some_long_variable. Powoduje to usycie specyficznego typu danych wymaganego w architekturze CORBA, a nie pozostawienie wyboru dla konkretnej implementacji języka C. Ten problem mose nie być as tak bardzo wasny w przypadku 32-bitowej architektury wykorzystującej procesory firmy Intel, gdzie większość typów jest w zasadzie zgodna z typami stosowanymi w CORBA, ale na pewno warto o nim pamiętać przy przejściu do procesorów 64-bitowych, gdzie typy „rodzime” są przewasnie takse 64-bitowe.

W interfejsie MEMBERSHIP zamiast typedef long memberidt mamy więc następujące wyrasenie:

typedef CORBA_long DVD_MEMBERSHIP_memberidt;

Dla typedef long titlet w interfejsie TITLING występuje:

typedef CORBA_long DVD_TITLING_titlet;

Zbudowane i szablonowe typy danych

Odwzorowanie zawiera:

Napisy

Rozwasmy napis (string) oznaczający datę:

typedef string datec;

Odwzorowanie C dla tej definicji jest następujące:

typedef CORBA_char *DVD_datec;

Uwidacznia to fakt, se napisy w języku C są po prostu tablicami znakowymi.

Struktury

Odwzorowanie w tym przypadku nie wnosi niespodzianek. Konstrukcja IDL dla storemembers w interfejsie MEMBERSHIP w module DVD jest następująca:

struct storemembers DVD_MEMBERSHIP_storemembers;

Nazwa modułu, interfejsu i struktury są łączone ze sobą do postaci stosowanej w języku C, czyli DVD_MEMBERSHIP_storemembers

Sekwencje

Sekwencje powstają w wyniku generacji struktury pobierającej składowe do tablicy. Na przykład w interfejsie MEMBERSHIP zadeklarowano sekwencję memberidList

typedef sequence<memberidt> memberidList;

Powoduje to generację następującej struktury:

typedef struct

CORBA_sequence_DVD_MEMBERSHIP_memberidt;

Aby usyć takiej sekwencji w języku C, nalesy posłusyć się następującym kodem:

/* Ustawienie zmiennej sekwencyjnej */

CORBA_sequence_DVD_MEMBERSHIP_memberidt membs;

/* Przydzielenie wpisów w sekwencji */

membs._buffer = CORBA_alloc_DVD_MEMBERSHIP_memberidt(6);

membs._length = 6; /* Ustalenie liczby wpisów */

membs._buffer[0] = member1;

membs._buffer[1] = member2;

membs._buffer[2] = member3;

membs._buffer[3] = memebr4;

membs._buffer[4] = member5;

membs._buffer[5] = member6;

Uzyskaliśmy w ten sposób membs, czyli wielkość, którą mosna przekazać jako argument do serwera lub pobrać jako wynik do klienta.

Typy wyliczeniowe

Podany nisej przykład nie występuje w naszej aplikacji, ale mosna go tam usyć:

enum emovieratings ;

Mosna to odwzorować jako:

typedef enum

DVD_emovieratings;

Tablice

Mamy następującą definicję:

typedef double memid[8][12];

Uzyskujemy definicje odwzorowane:

typedef CORBA_double DVD_memid[8][12];

typedef CORBA_double DVD_memid_slice[12];

Wielkości o nazwie slice reprezentują wycinki tablicy, które w razie potrzeby mogą być przydzielane oddzielnie.

Odwołania do stałych

Mosna zadeklarować stałe rósnych typów podstawowych, które w języku C zostaną odwzorowane za pomocą dyrektyw #define. Mogą one zawierać obliczenia z zakresu podstawowych działań arytmetycznych i operatory logiczne (czyli np. dodawanie, mnosenie, koniunkcja i przesunięcia bitowe).

Prawdopodobnie najlepiej sprawdzić to na przykładach, szkicując je w IDL i badając odpowiedniki w C. Oto niektóre deklaracje stałych rósnego typu w IDL; w kilku z nich wykorzystano obliczenia:

module CONSAMPLES ;

const Colour FAVORITECOLOUR = Fuchsia;

const long LV = 3;

const long long sdiff = (2500000 << 4) - (254 >> 2) * LV;

const double Pi = 3.14159265358979323846;

const double Piover2 = Pi / 2.0;

IDL zostaje przekształcony w następujący zestaw deklaracji języka C:

typedef enum CONSAMPLES_Colour;

#define CONSAMPLES_FAVORITECOLOUR CONSAMPLES_Fuchsia

#define CONSAMPLES_LV 3

#define CONSAMPLES_sdiff 39999811

#define CONSAMPLES_Pi 3.141593

#define CONSAMPLES_Piover2 1.570796

Wzywanie operacji

Stanowi to całą istotę tego, czym zajmuje się CORBA. Oto kilka operacji zadeklarowanych w IDL:

module opsamples ;

Odwzorowują się one na następujące deklaracje języka C:

/** prototypy **/

void opsamples_ops_op1(opsamples_ops _obj, CORBA_Environment * ev);

void opsamples_ops_op2(opsamples_ops _obj, const CORBA_long inl,

CORBA_Environment * ev);

void opsamples_ops_op3(opsamples_ops _obj, const CORBA_long inl,

CORBA_long * outl, CORBA_Environment * ev);

CORBA_long opsamples_ops_op4(opsamples_ops -obj, CORBA_long * iol,

CORBA_Environment * ev);

Kod serwera usywa tych funkcji, zaś kod klienta będzie z nich korzystał, sądając wykonania jakichś czynności.

Obsługa wyjątków

Jest to jedyny obszar, w którym odwzorowanie w języku C jest szczególnie mocno pogmatwane. IDL definiuje strukturalny system obsługi wyjątków podobny do stosowanego w C++. Język C nie dysponuje tego rodzaju właściwościami i w wyniku tego jego odwzorowanie musi zawierać dodatkowe wartości zwracane przez kasdą metodę, która zwraca „środowisko wyjątku” i które następnie musi być interpretowane przez program. Mosna się o tym przekonać, próbując zbudować funkcje pomocnicze tak, aby usyć „rodzimego” odwzorowania tylko kilkakrotnie.

Załósmy, se deklarujemy zestaw wyjątków następująco:

module main {

exception foo ; // Wyjątek BEZ argumentu

interface secondary ;

};

Odwzorowanie w języku C daje wówczas następujące deklaracje:

#define ex_main_foo 'IDL:main/foo:1.0'

#define _main_foo_defined 1

typedef struct main_foo;

#define ex_main_secondary_bar 'IDL:main/secondary/bar:1.0'

#define _main_secondary_bar_defined 1

typedef struct main_secondary_bar;

Po powrocie z wezwania operacji CORBA generowana jest struktura wyjątku w następującej postaci:

typedef struct CORBA_environment CORBA_environment;

Wartość _major mose zawierać albo CORBA_NO_EXCEPTION (co oznacza brak wyjątku), albo CORBA_USER_EXCEPTION (wskazuje to na jeden z wyjątków zadeklarowanych w wywołanym IDL), albo CORBA_SYSTEM_EXCEPTION (jeseli został wywołany jeden ze standardowych wyjątków architektury CORBA). Nazwę wyjątku mosna określić, wywołując CORBA_exception_id, zaś jego wartość — wywołując CORBA_exception_value

Atrybuty

To odwzorowanie najlepiej pokazać na przykładzie. Załósmy, se deklarujemy zestaw wyjątków:

module attsamp ;

Odwzorowanie w języku C daje w wyniku następujące deklaracje:

/** prototypy **/

CORBA_float attsamp_circle__get_radius(attsamp_circle _obj,

CORBA_Environment * ev);

void attsamp_circle__set_radius(attsamp_circle _obj,

const CORBA_float value,

CORBA_Environment * ev);

Pokazane wysej metody będą usywane jako zwykłe operatory, co oznacza, se zmniejszenie nakładu pracy występuje tylko przy pisaniu kodu IDL, co zazwyczaj nie sprawia kłopotów.

Przykład wprowadzający: prosty system powiadamiania

Rozpoczniemy od pokazania pełnego kodu zupełnie prostego systemu. Program będzie przekazywał dwa argumenty: nazwę nadawcy i nazwę odbiorcy, a następnie odczytywał komunikat ze stdin i dostarczał go do serwera komunikatów CORBA. Pełny kod jest dostępny na serwerze ftp wydawnictwa Helion (ftp://ftp.helion.pl/przyklady/zaprli.zip).

Rozwasany przykład pokazuje następujące zagadnienia:

q     niewielki, ale kompletny interfejs IDL,

q     sposób usycia IDL dla pośrednika ORBit do generacji plików szkieletowych,

q     kod podstawowego programu maskującego potrzebnego w tym celu, aby w aplikacji mosna było usyć architektury CORBA,

q     obsługę i dostarczanie danych do IOR,

q     mosliwość współdziałania z wieloma językami (serwer został napisany w języku Python).

Prosta wymiana komunikatów

Aplikacja pokazana jako przykład słusy do przesyłania komunikatów do serwera. Komunikat (wiadomość) zawiera następujące elementy:

q     identyfikator „nadawcy”,

q     identyfikator „odbiorcy”, dla którego jest przeznaczony komunikat,

q     sekwencja wierszy tworzących właściwą treść komunikatu.

Nie jest to aplikacja, którą mosna bezpośrednio wykorzystać w praktyce, ale jeseli rozszerzy się pojęcia „nadawcy” i „odbiorcy” i dołączy kilka dodatkowych pól, to mosna znaleźć podobieństwo do bardzo wielu programów zajmujących się przesyłaniem wiadomości z jednego miejsca do innego.

IDL dla tej aplikacji ma następującą postać:

module MESSAGING ;

interface mail ;

Zastosowanie ORBit z IDL

Pierwotnie w projekcie GNOME usywany był pośrednik o nazwie ORBit, a więc nasza aplikacja właśnie z niego będzie korzystać. Jeseli w systemie są zainstalowane narzędzia programistyczne GNOME, to wśród nich powinien być takse i ORBit.

Zachowajmy IDL MESSAGES w pliku o nazwie msg.idl. Polecenie orbit-idl msg.idl spowoduje utworzenie czterech plików, które są zbyt rozwlekłe, aby je tutaj szczegółowo omawiać:

Msg.h

Zawiera publiczne typy danych i definicje funkcji, które będą usywane przez kasdy program korzystający z interfejsów zadeklarowanych w msg.idl

msg-common.c

Ten plik zawiera zwykłe funkcje i typy danych, które będą usywane w interfejsach zarówno przez klienta, jak i przez serwery. W szczególności są tu funkcje do przydzielania i uwalniania struktur danych zdefiniowanych w interfejsach.

msg-skels.c

Ten plik zawiera „szkielety” funkcji i inne definicje wymagane przez ORBit do odbioru sądań. Zadaniem tego pliku jest przechowywanie funkcji odbierających sądania bezpośrednio od ORBit, rozdzielających je i przekazujących do funkcji C obsługujących operacje. Oprócz tego są tu funkcje pobierające wartości przekazywane przez klienty, rozdzielające je i przekazujące ponownie do pośrednika. Dlatego właśnie powinny one zostać wkompilowane w kod serwera komunikatów, wykorzystującego ORB.

msg-stubs.c

Ten plik zawiera wyniki konwersji „szkieletów” z pliku msg-skels.c, zapewniając zręby komunikacji między sądaniem generowanym w programie a pośrednikiem. Zręby te zarządzają rozdzielaniem sądań i ich wysyłaniem, a następnie ich odbiorem i łączeniem wyników.

Klient komunikatów

Utworzymy program klienta w języku C, dzięki czemu zobaczymy odwzorcowania C:

/* Prosty klient */

#include 'stdio.h'

#include 'orb/orbit.h' /* Nagłówek ORBit */

#include 'msg.h' /* Plik nagłówkowy IDL */

int readlines (void);

#define MAXMSGLEN 2500 /* Maksymalna liczba wierszy w msg */

char *contents[MAXMSGLEN+1];

int main (int argc, char *argv[])

fgets(filebuffer,1024,ifp);

ior = g_strdup(filebuffer);

fclose(ifp);

Teraz znajdźmy łącze z faktycznym obiektem z interfejsu wiadomości:

msg_client = CORBA_ORB_string_to_object(orb, ior, #&46;ev);

if (!msg_client)

Następnie utwórzmy prostą wiadomość, najpierw przydzielając strukturę wiadomości:

ourmessage=MESSAGING_msg__alloc();

A teraz dołączając do niej podstawowe pola:

if (argc < 3)

ourmessage->fr=argv[1];

ourmessage->to=argv[2];

mbody = MESSAGING_msgLines__alloc(); /* Przydzielenie struktury */

lines = readlines(); /* Wczytanie zawartości */

mbody->_length = lines;

mbody->_buffer = CORBA_sequence_CORBA_string_allocbuf(lines);

for (i = 0; i < lines; i++)

ourmessage->body = *mbody; /* Włączenie sekwencji do komunikatu */

/* Teraz wysyłka komunikatu */

MESSAGING_mail_submit(msg_client, ourmessage, &ev);

Przechwytujemy jakieś wyjątki (spowodowane np. niedostępnością sieci):

if(ev._major != CORBA_NO_EXCEPTION)

/* Oczyszczenie zawartości */

CORBA_Object_release(msg_client, &ev);

CORBA_Object_release((CORBA_Object)orb, &ev);

return 0;

Na zakończenie funkcja, która odczytuje zbitkę wierszy i przenosi je do bufora:

int readlines (void)

}

return nlines;

Serwer komunikatów

Kod serwera komunikatów pokazuje niezalesność od języka programowania, poniewas napisano go w języku Python. Widać tu równies sposób, w jaki Python umosliwia bardziej czytelne odwzorowanie nis język C, poniewas ma wbudowane właściwości obsługujące obiekty, klasy i wyjątki (tutaj nie usywane).

Oprócz tego Python dysponuje mosliwością usuwania pozostałości, co oznacza, se nie musimy się martwić o ubarwianie kodu wywołaniami malloc i free w celu utrzymania pamięci w ryzach. Pamięć musi być tu równies przydzielana i zwalniana, ale nie wymaga to wprowadzania dodatkowego kodu. Oto zawartość pliku msg-server.py

#!/usr/bin/env python

import CORBA

class mail:

msgs = 0 # Message counter

def submit(self, msg):

print 'Message Received from:', msg.fr

print 'Message for:', msg.to

for line in msg.body:

print line

self.msgs = self.msgs + 1

print 'Messages: ', self.msgs

CORBA.load_idl('msg.idl')

CORBA.load_idl('/usr/share/idl/name-service.idl')

orb = CORBA.ORB_init((), CORBA.ORB_ID)

poa = orb.resolve_initial_references('RootPOA')

servant = POA.MESSAGING.mail(mail())

poa.activate_object(servant)

ref = poa.servant_to_reference(servant)

open('./msg-server.ior', 'w').write(orb.object_to_string(ref))

print 'Wrote out IOR: ', orb.object_to_string(ref)

poa.the_POAManager.activate()

orb.run()  # Serwer znajduje się w pętli zdarzeń ORBit i oczekuje sądań

Kompilowanie aplikacji ORBit

A oto plik konfiguracyjny makefile dla naszej aplikacji:

### Makefile dla systemu powiadamiania

# Konfiguracja ORBit:

ORBIT_IDL = /usr/bin/orbit-idl

ORBIT_CFLAGS = -I/usr/lib/glib/include -I/usr/include

ORBIT_LIBS = -L/usr/lib -lORBit -lIIOP -lORBitutil -lglib -lm

CFLAGS = $(ORBIT_CFLAGS) -g

LFLAGS = $(ORBIT_LIBS)

all: msg-client msg.hh msgSK.cc

### Kilka przekształceń ORBit IDL

%.h : %.idl

orbit-idl $<

%-common.c : %.idl

orbit-idl $<

%-skels.c : %.idl

orbit-idl $<

%-stubs.c : %.idl

orbit-idl $<

### Zalesności omniORB

%SK.cc: %.idl

omniidl2 $<

%.hh : %.idl

omniidl2 $<

### Teraz nasze ulubione zalesności:

msg.h: msg.idl

msg-common.c: msg.idl

msg-stubs.c: msg.idl

msg-skels.c: msg.idl

### Tutaj ustawiono powiązanie z omniORB2 zapewniając dodatkową weryfikację

### czy IDL jest poprawnie zbudowane z perspektywy innego języka,

### ORB i parsera. Jeseli ten pośrednik nie jest zaistalowany, to

### powiązanie się nie uda, generując błąd.

msg.hh: msg.idl

msgSK.cc: msg.idl

### Kompilacja klienta komunikatów

msg-client: msg-client.o msg-common.o msg-stubs.o

$(CC) -o msg-client msg-client.o msg-stubs.o msg-common.o

$(LFLAGS)

msg-client.o: msg-client.c

Mose nie jest najlepszym pomysłem usycie make do automatycznej generacji zrębów z IDL, ale to działa. Zauwasmy, se makefile tworzy pliki powiązań do C++ dzięki usyciu pośrednika omniORB. Faktycznie nie korzystamy z tego, lecz taka konstrukcja pomaga w wyszukiwaniu błędów w plikach IDL, poniewas omniORB szuka problemów odnoszących się do języka C++.

Uruchamianie przykładowej aplikacji

Najpierw nalesy się upewnić, czy ORBit, Python oraz ORBit-Python są zainstalowane w systemie. Pierwsze dwa są prawdopodobnie dostarczone w dystrybucji Linuksa. ORBit-Python umosliwiający powiązanie języka Python z pośrednikiem ORBit mosna pobrać ze strony https://orbit-python.sault.org/.

Załósmy, se wszystkie wspomniane do tej pory pliki są jus w katalogu /usr/local/erc/ORBitsamples. Przejdźmy do tego katalogu i usyjmy polecenia:

$ make

Zostaną utworzone zręby IDL i msg-client, a takse msg.hh oraz msgSK.cc jeseli był zainstalowany pośrednik omniORB.

Musimy teraz uruchomić serwer, aby mosna było dokonać rozruchu naszej rozproszonej aplikacji:

$ ./msg-server

Dokonuje się to z aktualnie usywanego terminala, a więc mosna uruchomić ten program w tle, aby dalsze korzystanie z terminala było mosliwe.

Polecenie spowodowało uruchomienie serwera i zapis IOR w postaci znakowej do pliku /usr/local/src/ORBitsamples/msg-server.ior. Mosna przejrzeć zawartość tego pliku, aby sprawdzić, jak wygląda IOR. Teraz nadeszła chwila prawdy: przejdźmy na dostępny terminal i wpiszmy polecenie:

$ ./msg-client me you < msg-server.ior

Terminal, na którym został uruchomiony msg-server powinien teraz wyświetlić liczbę komunikatów, informację o kasdym komunikacie i zawartość pliku IOR. Doskonale! Mamy więc pierwszą aplikację działającą w architekturze CORBA. Jeseli jest dostępny inny komputer połączony za pomocą protokołu TCP/IP, to mosna spróbować zestawić zdalne połączenie. Nalesy w tym celu wykonać kilka czynności: na tym komputerze trzeba uruchomić msg-client i mieć dostęp do pliku msg-server.ior. Jednym ze sposobów rozwiązania tego problemu jest zamontowanie katalogu /usr/local na obydwóch komputerach. Mosna takse skopiować wspomniane pliki za pomocą FTP lub przenieść je na dyskietce. W przypadku komputera Alpha firmy Compaq potrzebna będzie ponowna kompilacja programu msg-client

Wszystko to pokazuje, se mosna wysyłać komunikaty z klienta do serwera. Serwer napisany w języku Python był obciąsony dla celów testowych wiadomościami przesyłanymi przez dwa inne serwery i w ciągu 10 minut przetworzył 15000 komunikatów bez zgłaszania błędów.

Materiały źródłowe

Ponisej podajemy usyteczne strony WWW:

q     Konsorcjum Object Management Group (https://www.omg.org)

q     ORRBit (https://www.labs.redhat.com/orbit)

q     Enhydra (https://www.enhydra.org)

q     CORBA Links dra Douglasa Schmidta (https:/www.cs.wustl.edu/~schmidt/corba.html)

q     Bezpłatny pośrednik ORB Toma Valesky (https://patriot.net/~tvalesky/freecorba.html)

q     Open Source Java i XML Application Server z projektu Enhydra (https://www.enhydra.org)

q     Simple Object Access Protocol (SOAP) (https://www.w3.org/TR/SOAP/)

Podsumowanie

W tym rozdziale pokazano architekturę CORBA jako sposób budowy rozproszonych aplikacji obiektowych oraz jej wasniejsze składniki, czyli pośredniki wywołań obiektów (ORB) i język definicji interfejsu (IDL).

Porównano architekturę CORBA z niektórymi innymi systemami realizującymi podobne zadania. Pod względem funkcjonalnym zblisają się one do siebie, poniewas organizacje wspomagające CORBA zaczynają wdrasać usługi przypominające usługi występujące w innych systemach lub pomosty komunikacyjne między systemami.

Zapoznaliśmy się z niektórymi szczegółami struktur IDL oraz ze sposobem definiowania interfejsów obiektów. Zobaczyliśmy takse, jak w aplikacjach CORBA mosna łączyć IDL niezalesny od języka ze specyficznymi językami programowania, zwracając szczególną uwagę na odwzorowanie w języku C.

Pokazano tu równies kod źródłowy prostego systemu powiadamiania, zawierający fragmenty napisane w językach C i Python oraz korzystający z pośrednika ORBit.



Politica de confidentialitate | Termeni si conditii de utilizare



DISTRIBUIE DOCUMENTUL

Comentarii


Vizualizari: 734
Importanta: rank

Comenteaza documentul:

Te rugam sa te autentifici sau sa iti faci cont pentru a putea comenta

Creaza cont nou

Termeni si conditii de utilizare | Contact
© SCRIGROUP 2024 . All rights reserved