Implementación de RMI

La implementación de RMI consta de tres capas de abstracción.

Estas capas de abstracción son:
  1. La capa Apéndice y esqueleto, que intercepta llamadas de métodos realizadas por el cliente a la variable de referencia de interfaz y redirige estas llamadas a un servicio RMI remoto.
  2. La capa Interfaz remota entiende cómo interceptar y gestionar las referencias realizadas por los clientes a objetos de servicio remoto.
  3. La capa inferior es la capa Transporte, que se basa en las conexiones TCP/IP entre máquinas de una red. Proporciona conectividad básica, así como algunas estrategias de penetración cortafuegos.
Este diagrama muestra la relación entre el programa cliente y el programa servidor a través del sistema RMI. El sistema RMI consta de los apéndices y esqueletos y la capa de referencia remota en el cliente y en el lado del servidor, enlazados por la capa de transporte.

En la parte superior de la capa TCP/IP, RMI utiliza un protocolo de nivel de conexión denominado Java™ Remote Method Protocol (JRMP), que funciona de este modo:

  1. Los objetos que requieren un comportamiento remoto deben ampliar la clase RemoteObject, normalmente a través de la subclase UnicastRemoteObject.
    1. La subclase UnicastRemoteObject exporta el objeto remoto para que esté disponible para atender las llamadas RMI entrantes.
    2. Al exportar el objeto remoto se crea un nuevo socket de servidor, que está vinculado a un número de puerto.
    3. También se crea una hebra que escucha las conexiones en dicho socket. El servidor se registra con un registro.
    4. Un cliente obtiene detalles de la conexión al servidor desde el registro.
    5. Al utilizar la información del registro, que incluye el nombre de host y los detalles de puerto del socket que escucha el servidor, el cliente se conecta al servidor.
  2. Cuando el cliente emite una invocación del método remoto al servidor, crea un objeto TCPConnection, que abre un socket al servidor en el puerto especificado y envía la información de cabecera RMI y los argumentos organizados a través de esta conexión utilizando la clase StreamRemoteCall.
  3. En el servidor:
    1. Cuando un cliente se conecta al socket del servidor, se asigna una nueva hebra para ocuparse de la llamada entrante. La hebra original puede continuar escuchando el socket original para que se pueden realizar llamadas adicionales de otros clientes.
    2. El servidor lee la información de cabecera y crea un objeto RemoteCall propio para tratar con los argumentos de RMI desorganizados del socket.
    3. El método serviceCall() de la clase Transport atiende la llamada entrante asignándola
    4. El método dispatch() llama al método apropiado en el objeto e inserta el resultado de nuevo en la conexión
    5. Si el objeto de servidor emite una excepción, el servidor la capta y la organiza hacia abajo de la conexión en lugar del valor de retorno.
  4. De nuevo en el extremo cliente:
    1. El valor de retorno de RMI se desorganiza y vuelve del apéndice de nuevo al propio cliente.
    2. Si se emite una excepción desde el servidor, se desorganiza y genera desde el apéndice.