5
pág. 1 Aplicaciones prácticas con RMI (Remote Method Invocation) En este apartado se explicará, con un ejemplo concreto, los pasos seguidos para elaborar una aplicación con objetos distribuidos RMI. Esta aplicación ejemplo proporcionará un servicio que acepta peticiones de tareas concretas especificadas por parte de los clientes. Es decir, cada cliente puede especificar la tarea que desea que el servidor le realice, utilizando para ello el paso de objetos serializados. La figura A.1 muestra un esquema del proceso paso por paso en la elaboración de una aplicación RMI.[6] Figura: Secuencia de pasos para programar aplicaciones RMI La secuencia indicada en la figura A.1 es la siguiente theenumialph@enumi theenumi) 1. En primer lugar se escribe la interfaz remota del servidor, que en este caso se llamará ejecutor. Toda interfaz remota debe declararse como public y debe extender la interfazjava.rmi.Remote. Además, esta interfaz debe definir los métodos que serán accesibles remotamente. Por último cada uno de estos métodos debe manejar la excepciónjava.rmi.RemoteException. La segunda interfaz necesitada para este ejemplo define el tipo Tarea. Este tipo es utilizado como un argumento del método ejecutar del interfazejecutor. Esta segunda interfaz permite definir desde el lado cliente la tarea (Tarea) que debe realizar el servidor y será pasada dinámicamente como argumento del método remoto. Observamos que la interfaz Tarea extiende el interfaz java.io.Serializable. RMI utiliza el mecanismo de serialización de objetos para transportar objetos entre máquinas virtuales. Tarea no es un objeto accesible remotamente, sino que es enviada por el cliente como argumento al servidor. En definitiva el objeto ejecutor del lado servidor queda a disposición de ejecutar tareas Tarea que le soliciten los clientes. El código de la interfaz remota ejecutor es el siguiente:

Aplicaciones Prácticas Con RMI

Embed Size (px)

DESCRIPTION

tarea

Citation preview

pág. 1

Aplicaciones prácticas con RMI (Remote Method Invocation)

En este apartado se explicará, con un ejemplo concreto, los pasos seguidos para elaborar una aplicación con objetos distribuidos RMI. Esta aplicación ejemplo proporcionará un servicio que acepta peticiones de tareas concretas especificadas por parte de los clientes. Es decir, cada cliente puede especificar la tarea que desea que el servidor le realice, utilizando para ello el paso de objetos serializados.

La figura A.1 muestra un esquema del proceso paso por paso en la elaboración de una aplicación RMI.[6]

Figura: Secuencia de pasos para programar aplicaciones RMI

La secuencia indicada en la figura A.1 es la siguiente theenumialph@enumi theenumi)

1. En primer lugar se escribe la interfaz remota del servidor, que en este caso se llamará ejecutor. Toda interfaz remota debe declararse como public y debe extender la interfazjava.rmi.Remote. Además, esta interfaz debe definir los métodos que serán accesibles remotamente. Por último cada uno de estos métodos debe manejar la excepciónjava.rmi.RemoteException. La segunda interfaz necesitada para este ejemplo define el tipo Tarea. Este tipo es utilizado como un argumento del método ejecutar del interfazejecutor. Esta segunda interfaz permite definir desde el lado cliente la tarea (Tarea) que debe realizar el servidor y será pasada dinámicamente como argumento del método remoto. Observamos que la interfaz Tarea extiende el interfaz java.io.Serializable. RMI utiliza el mecanismo de serialización de objetos para transportar objetos entre máquinas virtuales. Tarea no es un objeto accesible remotamente, sino que es enviada por el cliente como argumento al servidor. En definitiva el objeto ejecutor del lado servidor queda a disposición de ejecutar tareas Tarea que le soliciten los clientes.

El código de la interfaz remota ejecutor es el siguiente:

pág. 2

package callback; import java.rmi.*; public interface ejecutor extends Remote{ public String ejecutar(Tarea t) throws RemoteException; }

El código de la interfaz Tarea es el siguiente:

package callback; import java.io.Serializable; public interface Tarea extends Serializable{ public String recado(); }

La interfaz ejecutor contiene un único método ejecutar, que recibe como argumento un objeto de la clase Tarea, que es la interfaz definida por el cliente. De esta forma el cliente implementa la tarea (de cálculo, por ejemplo) que desea realice el servidor. Para ello define el método recado.

2. Se implementa la interfaz remota. La clase que la implementa debe heredar de RemoteServer y lo habitual es hacerlo heredando de UnicastRemoteObject. El código de la implementación ejecutor_Imp es el siguiente:

3. package callback; 4. import java.rmi.*; 5. import java.rmi.server.*; 6. 7. public class ejecutor_Imp extends UnicastRemoteObject 8. implements ejecutor { 9. protected ejecutor_Imp() throws RemoteException { 10. super(); 11. } 12. public String ejecutar(Tarea t) throws RemoteException { 13. return t.recado(); 14. } 15. }

Ésta es la implementación desde el lado servidor de la interfaz ejecutor. Utiliza el constructor de la clase de la que hereda, UnicastRemoteObject y define el métodoejecutar(Tarea t), que devuelve la resolución del método recado() del objeto Tarea que ha sido pasado como parámetro.

16. Se generan los archivos stub y skeleton a partir de la clase que implementa la interfaz remota. Para ello se utiliza el compilador rmic. Para ejecutarlo hacemos rmic nombre_claseo bien rmic -d directorio nombre_clase para especificar una ubicación destino concreta.

Como resultado de esta operación se obtienen dos archivos:

o ejecutor_Imp_Stub.class

pág. 3

o ejecutor_Imp_Skel.class 17. Se inicia el servicio de registro RMI, rmiregistry. Un host que quiera exportar

referencias remotas a sus métodos de modo que los stubs puedan acceder a ellos, debe estar ejecutando un servidor de registro RMI.

Este servicio se inicia en entornos Linux:

rmiregistry &

En entornos Windows:

start rmiregistry

La aplicación rmiregistry crea un objeto Registry, que escucha por un puerto, a la espera de peticiones de procesos clientes que busquen objetos remotos en el registro RMI. Cabe destacar que, cara al servidor de registro RMI, todos los procesos actúan como clientes, tanto los servidores de objetos remotos como los clientes. Un servidor que va a registrar sus objetos remotos debe estar en el mismo host que ejecuta el servidor de registro RMI.

18. Se inicia un proceso servidor y se registra en el rmiregistry. Una vez compilada y ejecutada, queda registrada.

El código para la implementación del servidor es el siguiente:

package callback; import java.rmi.*; public class servidor { private servidor(){ try{ if (System.getSecurityManager()==null) System.setSecurityManager(new RMISecurityManager()); ejecutor imp=new ejecutor_Imp(); Naming.rebind("rmi://192.168.2.2/Motor_Computo",imp); }catch(Exception e){ System.out.println("Error: "+e.getMessage()); e.printStackTrace(); } } public static void main(String args[]){ System.out.println("Levantando el servidor..."); servidor server=new servidor(); } }

El servidor, en primer lugar, instala un gestor de seguridad. A continuación crea un objeto de la clase que implementa la interfaz remota y lo publica.

pág. 4

En el ejemplo que nos ocupa estamos suponiendo que las clases necesarias residen en las máquinas implicadas, por lo que no sería necesario el uso de un gestor de seguridad.

19. Se escribe la clase cliente. En esta parte se incluye la implementación de la interfaz Tarea vista previamente, que utilizará el cliente para solicitar la ejecución de una tarea determinada.

El código de la clase que implementa la interfaz Tarea es el siguiente:

package callback; public class tarea_Imp implements Tarea{ public String recado() { return "Hello World"; } }

El código para la implementación del cliente es el siguiente:

package callback; import java.rmi.*; public class cliente { public static void main(String args[]){ try{ if (System.getSecurityManager()==null) System.setSecurityManager(new RMISecurityManager()); ejecutor ej=(ejecutor) Naming.lookup("rmi://192.168.2.2/Motor_Computo"); Tarea tarea=new tarea_Imp(); String respuesta=ej.ejecutar(tarea); System.out.println(respuesta); }catch(Exception e){ System.out.println("Error: "+e.getMessage()); } } }

La clase Tarea_Imp implementa la interfaz Tarea, vista anteriormente. En este caso, define el método recado() como un simple "Hello World". Es decir, la tarea que el cliente quiere que realice el servidor es devolverle la frase "Hello World".

Al igual que en el lado servidor, el cliente empieza creando e instalando un gestor de seguridad. A continuación localiza el objeto remoto y crea un objeto de la clase Tarea_Imppara solicitar al servidor que ejecute esa tarea.

20. Se compila la clase cliente 21. Se inicia un proceso cliente.

pág. 5

Figura: Proceso servidor en ejecución

Figura: Proceso cliente en ejecución