Remote Method Invocation

Wstęp
RMI (ang. Remote Method Invocation) - zdalne wywołanie metod. RMI jest to mechanizm umożliwiający wywołanie metod zdalnych obiektów wykonujących się w innych maszynach wirtualnych Javy, które mogą znajdować się na innych komputerach. Zgodnie z terminologią RMI obiekt, który wywołuje metodę zdalną, nazywany jest obiektem klienta, a obiekt zdalny obiektem serwera. Proces wywoływania zdalnej metody przez obiekt klienta odbywa się poprzez wywołanie metody obiektu zastępczego zwanego namiastką, która znajduje się zawsze na kliencie. Przesyła ona parametry wywołania zdalnej metody za pomocą bloku bajtów. Każdy z parametrów reprezentowany jest za pomocą kodu niezależnego od rodzaju maszyny,a przesyłane obiekty są odpowiednio serializowane. Cały proces jest dość skąplikowany, ale naszczęście wykonywany automatycznie i w sposób niewidoczny dla programisty.
Program klienta operuje zdalnymi obiektami serwera jednak nie posiada ich lokalnych kopii, który znajdują się wyłącznie na serwerze. Klient musi wiedzieć, jakie operacje na tych obiektach są dozwolone. Możliwości te wyraża się za pomocą interfejsu współdzielonego przez klienta i serwer.
import java.rmi.*;
interface Kalkulator extends Remote{
int dodaj(int x,int y) throws RemoteException;
}
Interfejs musi rozszerzać interfejs Remote zdefiniowany w pakiecie java.rmi, natomiast wszystkie metody muszą także deklarować możliwośc zgłoszenia wyjątku RemoteException.
Serwer
Serwer musi implementować klasę, która wykonuje medody wyspecyfikowane przez interfejs i stanowi rozszerzenie klasy UnicastRemoteObject, która umożliwia zdalny dostęp do obiektów serwera.
import java.rmi.*;
import java.rmi.server.*;
public class KalkulatorImpl extends UnicastRemoteObject implements Kalkulator{
public KalkulatorImpl() throws RemoteException {
}
public int dodaj(int x, int y) throws RemoteException {
return x+y;
}
}
Klient uzyskuje dostęp do obiektów serwera za pośrednictwem obiektu namiastki implementującego ten interfejs, która tworzymy za pomocą polecenia:
rmic KalkulatorImpl
Zostanie wowczas utworzony plik KalkulatorImpl_Stub.class (we wcześniejszych wersajach javy do JDK 5.0 tworzona byla również klasa szkieletu Kalkulator_Skel.class). To jednak nie koniec roli serwera. Klient, aby skorzystać z usług zdalnego obiektu znajdującego się na serwerze musi pobrać namiastkę, a program serwera zarejestrować obiekt, korzystając z usługi rejestru początkowego. Obiekt serwera jest rejestrowany przez podanie jego referencji i nazwy:
KalkuatorImpl calc = new KalkulatroImpl();
Context naming = new InitialContext();
naming.bind("kalkulator",calc);
Cały kod klasy serwera wygląda następująco:
import java.rmi.*;
import java.rmi.server.*;
import javax.naming.*;
public class Serwer {
public static void main(String[] args){
try{
String url = "http://localhost/"; //adres serwera
System.setProperty("java.rmi.server.codebase",url);
KalkulatorImpl calc = new KalkulatorImpl();
Context naming = new InitialContext();
naming.bind("rmi:kalkulator",calc); //rejestrowanie obiektu calc
}
catch (Exception e){
e.printStackTrace();
}
}
}
Czas najwyższy na uruchomienie serwera. Jednak korzysta no z usługi rejestru początkowego RMI, więc najpierw musimy ją uruchomić.
W systemie Unix:
rmiregistry &
W systemie Windows:
start rmiregistry
Następnie uruchamiamy serwer.
W systemie Unix:
java Serwer &
W systemie Windows:
start java Serwer
Klient
Kod klasy klienta, który wywoluje metodę dodaj zdalnego obiektu klasy Kalkulator wygląda następująco:
import java.rmi.*;
import java.rmi.server.*;
import javax.naming.*;
public class Klient {
public static void main(String[] args){
//wczytanie pliku polityki
System.setProperty("java.security.policy","client.policy");
//instalowanie menadzera bezpieczeństwa
System.setSecurityManager(new RMISecurityManager());
String url = "rmi://localhost/";
try{
Context naming = new InitialContext();
Kalkulator calc = (Kalkulator) naming.lookup(url + "kalkulator");
int wynik = calc.dodaj(2,3); //wywołanie zdalnej metody
System.out.println(wynik);
}
catch (Exception e){
e.printStackTrace();
}
}
}
Aby zezwolić klientowi na połączenia do rejestru i obiektów serwera, musimy utworzyc odpowiedni plik polityki client.policy.
grant{
permission java.net.SocketPermission
"*:1024","connect";
permission java.net.SocketPermission
"*:80”,”connect";
};
Plik client.policy umieszczamy w tym samym katalogu, w ktorym znajdują się pliki klienta. Możemy już uruchomić program klienta.
java Klient
Przesyłanie obiektów
Obiekty przesyłane do serwera są automatycznie serializowane przez namiastkę i rozszeregowywane na serwerze. Większość standardowych klas zaimplementowanych w bibliotekach implementuje interfejs serializacji. Tworząc własną klasę należy pamiętać o zaimplementowaniu interfejsu Serializable.
public class Punkt implements Serializable {
public Punkt(){};
}
Aby dodawać komentarze musisz być zalogowany!
