Implementacja RMI

Implementacja RMI składa się z trzech warstw abstrakcji.

Te warstwy abstrakcji są następujące:
  1. Warstwa Stub and Skeleton , która przechwytuje wywołania metody wykonywane przez klienta do zmiennej odwołania do interfejsu i przekierowuje te wywołania do zdalnej usługi RMI.
  2. Warstwa Remote Reference (Remote Reference) rozumie sposób interpretacji i zarządzania odwołaniami od klientów do obiektów usług zdalnych.
  3. Warstwa dolna jest warstwą Transport , która jest oparta na połączeniach TCP/IP między maszynami w sieci. Zapewnia on podstawową łączność, jak również niektóre strategie penetracji zapory firewall.
Ten diagram przedstawia relację między programem klienckim a programem serwera za pośrednictwem systemu RMI. System RMI składa się z kodów pośredniczących i szkieletów oraz zdalnej warstwy referencyjnej zarówno na kliencie, jak i po stronie serwera, połączonych za pomocą warstwy transportowej.

W górnej części warstwy TCP/IP RMI korzysta z protokołu na poziomie łącznika o nazwie Java™ Remote Method Protocol (JRMP), który działa w następujący sposób:

  1. Obiekty, które wymagają zachowania zdalnego, powinny rozszerzać klasę RemoteObject , zwykle za pomocą podklasy UnicastRemoteObject .
    1. Podklasa UnicastRemoteObject eksportuje zdalny obiekt, aby udostępnić go do obsługi przychodzących wywołań RMI.
    2. Eksportowanie obiektu zdalnego tworzy nowe gniazdo serwera, które jest powiązane z numerem portu.
    3. Tworzony jest również wątek, który nasłuchuje połączeń na tym gnieździe. Serwer jest zarejestrowany w rejestrze.
    4. Klient uzyskuje szczegółowe informacje na temat nawiązywania połączenia z serwerem z rejestru.
    5. Korzystając z informacji z rejestru, która zawiera nazwę hosta i szczegóły portu gniazda nasłuchującego serwera, klient łączy się z serwerem.
  2. Gdy klient wysyła do serwera zdalne wywołanie metody, tworzy obiekt TCPConnection , który otwiera gniazdo na serwerze w podanym porcie i wysyła informacje nagłówka RMI oraz argumenty zestawione za pośrednictwem tego połączenia przy użyciu klasy StreamRemoteCall .
  3. Po stronie serwera:
    1. Gdy klient łączy się z gniazdem serwera, nowy wątek jest przypisywany do połączenia przychodzącego. Oryginalny wątek może kontynuować słuchanie oryginalnego gniazda, tak aby można było wykonać dodatkowe wywołania od innych klientów.
    2. Serwer odczytuje informacje nagłówkowe i tworzy obiekt RemoteCall , który jest właścicielem, aby zająć się unmarshowaniem argumentów RMI z gniazda.
    3. Metoda serviceCall() usług klasy Transport przychodzących wywołań przez rozsyłanie jej
    4. Metoda dispatch() wywoła odpowiednią metodę na obiekcie i wypycha wynik z powrotem w dół łącznika.
    5. Jeśli obiekt serwera zgłosi wyjątek, serwer przechwyci go i zestawiło go w dół zamiast wartości zwracanej.
  4. Z powrotem po stronie klienta:
    1. Wartość zwracana RMI jest unmarshalled i zwracana z kodu pośredniczącego z powrotem do samego kodu klienta.
    2. Jeśli wyjątek jest zgłaszany z serwera, to jest on unmarshalled i zgłaszany z kodu pośredniczącego.