Tecnología RMI

¿Que es RMI?

RMI es un paquete de JAVA que permite manejar objetos (y sus respectivos métodos) de manera remota, para utilizar los recursos de un servidor de manera transparente para el usuario local.

La manera en que RMI (y RPC en general) logra hacer esto, es por medio de lo que se conoce como STUBs. En el caso del STUB servidor, se conoce como SKELETON. Estos Stubs y Skeletons permiten que al momento de ser invocada la función remota esta pueda ser "simulada localmente"


La arquitectura

RMI puede verse como un modelo de cuatro capas:


Terminología

  • Objeto cliente: objeto cuyo método hace el llamado remoto.
  • Objeto servidor: Objeto remoto llamado
Notar que los roles de cliente y servidor aplican sólo a un llamado. Un objeto servidor luego puede ser cliente al hacer un llamado remoto.
  • Marshalling: es el proceso de codificación de los parámetros.
  • Stub: es un objeto que encapsula el método que deseamos invocar remotamente. Así el llamado remoto es semejante a un llamado local. Éste prepara información con la identificación el objeto remoto a invocar, el método a invocar y codificación de los parámetros (Marshalling).
  • Skeleton: es el objeto del lado del servidor que decodifica los parámetros, ubica el objeto llamado, llama el método deseado, codifica el valor retornado, y envía la información de regreso al stub.



Proceso de Desarrollo


  • 1. Definir la interface remota
  • 2. Programar la clase implementación 
  • 3. Compilar la clase implementación 
  • 4. Ejecutar del compilador de stubs con la clase compilada: rmic 
  • 5. Arrancar el registro RMI en el servidor:  rmiregistry 
  • 6. Ejecutar la aplicación servidor. 
  • 7. Ejecutar la aplicación cliente.

Pasos para crear un servidor RMI

Para este tutorial vamos a crear  una una aplicación que nos calcule el factorial para lo cual, crearemos un nuevo proyecto, en el IDE Netbeans.

1. Crear un nuevo proyecto
En este  proyecto implementaremos nuestro servidor.
2. Implementar una Interfaz

Las interfaces son una forma de especificar qué debe hacer una clase sin especificar el cómo.
Las interfaces tienen una semejanza con las clases abstractas, en el sentido que no tiene sentido definir objetos instancia de una interfaz. Igual que las clases abstractas clase asociada se comprometa a implementar todos los métodos en ellas definidos, pero en este caso la relación no es de herencia en plenitud, dado que no hay atributos en la definición de una interfaz.

3. Declarar la estructura del método factorial en la Interfaz.


  • Código de la Interfaz


 1 package vista;
 2 
 3 import java.rmi.Remote;//Importamos las librerias de java RMI Remote
 4 import java.rmi.RemoteException;
 5 //Extendemos del paquete Remoto RMI
 6 public interface Interfaz extends Remote {
 7     
 8 //Declaramos la operación de factorial con un parámetro con la exepcionRemota
 9     public int fact(int numero) throws RemoteException;
10 }
11 
4. Crear la clase Servidor
En el mismo paquete creamos la clase servidor con el método main, la cual se usara para ejecutar el servidor.
LocateRegistry
LocateRegistry se utiliza para obtener una referencia a un registro de objetos remotos de arranque en un host particular (incluido el host local), o para crear un registro de objetos remotos que acepte llamadas en un puerto específico.
createRegistry(int port)
Crea y exporta una Registryinstancia en el host local que acepta solicitudes en el especificado port.
 

  • Código del Servidor


 1 /*
 2  * To change this license header, choose License Headers in Project Properties.
 3  * To change this template file, choose Tools | Templates
 4  * and open the template in the editor.
 5  */
 6 package vista;
 7 //Importamos las librerías RMI
 8 import java.rmi.RemoteException;
 9 import java.rmi.registry.LocateRegistry;
10 import java.rmi.registry.Registry;
11 import java.rmi.server.UnicastRemoteObject;
12 import javax.swing.JOptionPane;
13 
14 /**
15  *
16  * @author Toshiba
17  */
18 public class Servidor extends UnicastRemoteObject implements Interfaz {
19 
20     public Servidor() throws RemoteException {
21         super();
22     }
23 
24     //Metodo main para ejecutar el servicio
25     public static void main(String[] args) {
26         try {
27             //Crear un Objeto de registros compartidos
28             Registry r = LocateRegistry.createRegistry(1099);
29             //Enlaza una referencia remota al nombre especificado en este registro.
30             r.bind("servidor", new Servidor());
31             //Mensaje de levantamiento del servicio exitoso
32             JOptionPane.showMessageDialog(null, "Servidor Conectado");
33         } catch (Exception e) {
34             System.out.println(e);
35             //Mensaje de Fallo
36             JOptionPane.showMessageDialog(null, "Servidor  no Conectado" + e);
37         }
38     }
39 
40     //Metodo Override 
41     //Contiene el metodo Remoto del Factorial
42     @Override
43     public int fact(int numero) throws RemoteException {
44         int f = 1;
45         for (int i = 1; i <= numero; i++) {
46             f *= i;
47         }
48         return f;
49     }
50 
51 }
52 
El primer proyecto consta de la Interfaz y la clase Servidor , la cuál contiene el método main del servicio y el método de la fracción.

5. Crear otro proyecto.
En este proyecto se consumirá el servicio remoto que se encuentra en el proyecto anterior, para lo cual
 se requiere copiar la interfaz del primer proyecto y pegarlo en el segundo proyecto.

Nota: los paquetes de ambos proyectos deben tener el mismo nombre para su reconocimiento con
 el servidor remoto.

6. Crear la clase Principal.
En el proyecto Usuario  crear la clase principal con el método main y realizar la conexión remota con el servico que se encuentra en el proyecto Factorial. Para ello lo haremos mediante la referencia del host y el puerto.


getRegisty(String host, int port)
Devuelve una referencia al objeto remoto Registryen el especificado hostport.

throws RemoteException
Una RemoteException es la superclase común para una serie de excepciones relacionadas con la comunicación
 que pueden ocurrir durante la ejecución de una llamada de método remoto. Cada método de una interfaz 
remota, una interfaz que extiende java.rmi.Remote, debe incluir RemoteException en su cláusula de 
lanzamientos.
    • Código de la clase Principal
     1 package vista;
     2 //Importamos las librerias del RMI
     3 import java.rmi.RemoteException;
     4 import java.rmi.registry.LocateRegistry;
     5 import java.rmi.registry.Registry;
     6 import javax.swing.JOptionPane;
     7 
     8 public class Principal {
     9 
    10 public static void main(String[] args) throws RemoteException {
    11 
    12         Principal p = new Principal();
    13         p.conectar();
    14     }
    15 
    16     public void conectar() throws RemoteException {
    17 
    18         try {
    19  //Devuelve una referencia al objeto remoto Registryen el 
    20    //especificado hosty port.
    21    Registry r = LocateRegistry.getRegistry("localhost", 1099);
    22  //Devuelve la referencia remota vinculada al nombre especificado
    23    // en este registro.
    24  Interfaz in = (Interfaz) r.lookup("servidor");
    25  System.out.println("conectando");
    26  //Creamos un ménu
    27  while (true) {
    28  String menu = JOptionPane.showInputDialog
    29
    30   ("FACTORIAL\n" + "1.-Factorial\n Presione CANCELAR para Salir");
    31   switch (menu) {
    32  case "1": {
    33  int num = Integer.parseInt(JOptionPane.showInputDialog
    34  ("Número a factorizar"));
    35  //Llamamos al metodo factorial encontrado en el proyecto
    36  // Factorial
    37  JOptionPane.showMessageDialog(null, "El factorial de " 
    38    + num + " es :" + in.fact(num));
    39                         break;
    40                     }
    41                 }
    42 
    43             }
    44 
    45         } catch (Exception e) {
    46             
    47         }
    48 
    49     }
    50 }
    Ahora proceder a ejecutar primero el servicio que se encuentra en el Proyecto Factorial y después el
    (Cliente) que lo encontramos en el proyecto Usuario la clase Principal.
    El resultado sera lo siguiente:
    Servidor corriendo.
    Cliente consumiendo del Servidor.
    
    
    
    









    Esta ha sido una pequeña explicación sobre el uso del RMI (Java Remote Method Invocation) .

    Conclusiones


    • La utilización de objetos en el desarrollo de sistemas distribuidos, presenta varias ventajas que permiten ocultar las dificultades inherentes a la distribución en niveles de abstracción inferiores. 

    • La invocación remota de métodos en Java parte del hecho de correr sobre una plataforma heterogénea.

    •   RMI posee todas las características de seguridad que hereda de la plataforma Java misma.

    Comentarios

    Entradas populares de este blog

    Introducción a la metodología RAD

    Sistema Clinico con PhpMaker

    Lenguaje de Programación Avanzada