Zdalne wywołanie metod
Ogólnie
RMI zawiera się w JDK l. l i późniejszej
Dostarczone są narzędzia do przygotowania aplikacji rozproszonych
javac - kompilacja klas
rmic — kompilator RMI — przygotowuje stub/skeleton aplikacji.
RMI jest to wywołanie zdalnych metod obiektów niemal tak jak lokalnie:
Serializacja obiektów - przekształcanie obiekty w strumień bajtów i przekazywanie ich dalej do zdalnych komputerów a tam zostają z powrotem przekształcone w obiekt.
Zdalne referecje - obiekt implementuje interfejs „Remote", przekazywane są zdalne referencje,
Obiekty bez „Remote" są przekazywane przez wartość jako kopie z użyciem mechanizmu serislizacji.
Architektura RMI
3 warstwy:
- stub/skeleton - trzon/szkielet,
- remote rference - zdalne referencje,
- transport - warstwa transportowa
Warstwowa budowa pozwala na ich wymianę i zmianę sposobu działania.
Implementacja
Java.rmi - klasy, interfejsy i wyjątki po stronie klienta,
Java.rmi.server - klasy, interfejsy i wyjątki po stronie serwera,
Java.rmi.registry- klasy, interfejsy i wyjątki służące do nazywania i lokalizowania zdalnych obiektów.
Etapy przygotowania aplikacji RMI
Projektowanie i implementacja komponentów, z których będzie się składać aplikacja RMI,
- Definicja zdalnych interfejsów,
- Implementacja zdalnych interfejsów i serwera
- Przygotowanie klienta używającego zdalnych interfejsów
kompilacja źródeł i wygenerowanie pni,
udostępnienie zdalnych obiektów w rejestrze RMI
- start rejestru,
uruchomienie serwera i klienta
Etapy przygotowania aplikacji RMI
Na etapie projektowania aplikacji określa się, jakie interfejsy zdalne aplikacja powinna udostępniać i kto będzie z nich korzystał. Na tym etapie odbywa się projektowanie zdalnych interfejsów, ich implementacja oraz implementacja programu klienta.
Kompilacja przebiega dwustopniowo. Najpierw kompilujemy wszystkie pliki źródłowe za pomocą programu javac,
następnie używamy kompilatora rmic, aby stworzyć pnie dla obiektów zdalnych.
Uruchomienie aplikacji serwera. Aplikacja może wystartować rejestr RMI programowo; możemy też wystartować go ręcznie, pisząc z linii poleceń:
> rmiregistry
Uruchamiamy aplikację kliencką. Z obiektów RMI udostępnionych na zdalnym serwerze może korzystać wiele programów równocześnie. Klasy, które udostępniamy powinny być napisane w sposób umożliwiający ich jednoczesne wykorzystanie przez wiele równoległych wątków.
Przykładowa aplikacja w RMI
Zadaniem serwera będzie przechowywanie obiektu trzymającego aktualną datę i czas.
Klient skorzysta ze zdalnego obiektu i wyświetli czas na konsoli.
Nasza klasa będzie miała tylko jedną metodę, która zwróci aktualny czas na serwerze.
import java.rmi.Remote;
import java.rmi.RemoteEx;
import java.until.Date;
public interface RemoteTime extends Remote
{ public Data getTime () throws
RemoteException; }
Przykładowa aplikacja w RMI - implementacja zdaln. interfejsu
mportjava.rmi.*;
mportjava.rmi,server,*;
mportjava.util.Date;
//klasa musi dziedziczyć po UnicastRemoteObject
// i implementować interfejs Remote
public class RemoteTimelmpl extends UnicastRemoteObject
implements Rernote, Serializable {
cd..
// konstruktor publicRemoteTirnelrnpl throws RernoteException {super(): }
// właściwa metoda wywoływana zdalnie
public Datę getTime() throws RemoteException { return new Date();}
cd..
// metoda ma i obowiązująca obiekt do import java.rmi.Remote;
rejestru RMI
publtc stattc votd main(String[] args) {
//ustawienie security managera
if(System.gelScairilyNhimiger() = null) {
Systetn.setSecurit>-Manager(newRMISecurityManager());
}
cd..
String name = "RemoteTime"; //nazwa udostępnianego obiektu
try { //uruchamiamy rejestr RMI
Registry r = LocateRegistry.createRegistry( 1099);
//tworzymy obiekt
RemoteTimelmpl rti = new RemoteTimeImpl();
// dowiadujemy go do rejestru RMI
r.rebind(name, rti);
System.out.println("Obiekt dowiązany do rejestru RMI"); } catch (Exception e) { System.err.println(" Btąd"+e.getMessage()); e.printStackTrace();}}}
Przykładowa aplikacja w RMI - przygotowanie klienta
import java.rmi.*;
import java.util.Date;
public class ReinoteTirneClient {
public static void main(String[] args) {
//ustawienie security managera
if (System. getSecurityManager() == null) { SystenisetSecurityManager(New RMiSecurityMariager());
cd..
try{
//nazwa zdalnego obiektu wraz z nazwą komputera, na którym jest udostępniony
String name = "// localhost/RemoteTime";
// wyszukanie zdalnego interfejsu w rejestrze
RemoteTime rt = (Datę) Naming.lookup(name);
cd..
// tu jest cale sedno, używania zdalnego obiektu, tak, jakby był lokalny
Datę d = rt.getTime();
// wyświetlamy otrzymany czas
System.out.println("Aktualny czas: "+d); } catch (Exception e) { System.err.println(" Btąd"+e.getMessage()); e.printStackTrace();}
Przykładowa aplikacja w RMI - kompilacja i uruchomienie
Kompilacja wszystkich programów przy pomocy
javac i
rmic -d . RemoteTimelmpl
Uruchomienie programu
- Uruchomienie rejestru RMI i dowiązanie do niego obiektu zdalnego (serwer):
> java RemoteTimelmpl
- W drugim oknie konsoli klient:
>java RemoteTimeClient
Podsumowanie
Zalety
- Proste pisanie aplikacji rozproszonych
- Przenoszenie całych obiektów
- Zwolnienie programisty z czuwania nad sieciowymi mechanizmami niskiego poziomu
Wady
- Ograniczenie do środowiska Java