Tema 2: Programación en Red, RMI

Anuncio
Llamada a procedimientos remotos
Tema 2:
Programación en Red,
RMI
1
Previo: Objetos e interfaces en JAVA
Interface 1
Data
{
m1
m2
m3
implementation
of methods
main()
public class Client {
private Client() {}
public static void main(String[] args) {
Hello server = (Hello) new Server();
String response = server.sayHello();
System.out.println("response: " +
response);
}
}
JAVA Remote Method Invocation
(I)
RMI es una implementación orientada a objectos del
paradigma de llamadas a procedimientos remotos. RMI
es una implementación solo en JAVA.
El objecto remoto provee metodos remotos que
pueden ser invocados por programas clientes
Un cliente invoca los metodos remotos de la misma
manera que se invocan metodos en objectos locales.
Object 2
Object 1
2
public interface Hello {
String sayHello();
}
remote object
object
public class Server implements Hello {
public Server() {}
public String sayHello() {
return "Hello, world!";
}
}
remote
interface
Main Cliente RMI
3
{
Data
m1
m2
m3
implementation
of methods
Main Servidor RMI
4
JAVA Remote Method Invocation (II)
Un cliente tiene que conocer este remote interface para
poder utilizarlo (Un registro RMI permite localizarlo).
En RMI un servidor exporta un remote object
registrandolo en un servicio de registro.
El objecto remoto implementa un remote interface, es
una extensión del interface Java (=se comporta igual),
Los parametros de entrada y salida de los metodos se
transmiten serializados.
Cliente RMI
Una aplicacion para invocar el metodo de un objecto remoto tiene que:
Localizar el objecto en un registro:
Registry RMI
remote
interface
{
Cliente RMI
Data
m1
m2
m3
implementation
of methods
Servidor RMI
5
Servidor RMI
Un servidor de
objetos remotos:
implementa
el
interface
de
metodos remoto,
Crea y exporta
objeto remoto,
Registrar objetos
en un registro RMI.
import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class Server implements Hello {
public Server() {}
public String sayHello() {
return "Hello, world!";
}
public static void main(String args[]) {
try {
Server obj = new Server();
Hello stub = (Hello) UnicastRemoteObject.exportObject(obj, 0);
client
registro
server
Registry registry = LocateRegistry.getRegistry();
Registrar(objecto)
registry.bind("Hello", stub);
localizar(nombre)
System.err.println("Server ready");
Ref. Objeto
} catch (Exception e) {
System.err.println("Server exception: " + e.toString());
Objecto.metodo()
e.printStackTrace();
}
}
7
}
Se invoca el metodo en el objecto devuelto con una invocación normal.
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Client {
private Client() {}
public static void main(String[] args) {
String host = (args.length < 1) ? null : args[0];
try {
Registry registry = LocateRegistry.getRegistry(host);
Hello stub = (Hello) registry.lookup("Hello");
String response = stub.sayHello();
System.out.println("response: " + response);
} catch (Exception e) {
System.err.println("Client exception: " + e.toString());
e.printStackTrace();
}
}
}
remote object
object
El objecto devuelto tiene que tener el cast del interface del objecto remoto,
El objecto devuelto se “comporta” como el objeto remoto.
client
registro
server
Registrar(objecto)
localizar(nombre)
Ref. Objeto
Objecto.metodo()
6
Interface Remote RMI
Un interface remoto en
RMI hereda de la clase
Remote. Se comporta
como cualquier interface
en Java y cualquier clase
puede implementarlo.
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface Hello extends Remote {
String sayHello() throws RemoteException;
}
La excepción java.rmi.Remote debe ser listada con la
sentencia throw en cada metodo del interface.
Esta excepción salta cuando ocurren errores durante el
procesamiento de la invocación de un método remoto, y
dicha excepción debe ser recogida por el programa que
efectua la invocación.
Existen multiples causas que hacen saltar las excepciones:
principalmente fallos de acceso o comunicación, o
problemas en RMI como no encontrar los stubs, etc.
8
Architectura RMI
Stubs y Skeletons en RMI
STUB se comporta
como un objeto
local para el
objecto cliente
SKELETON
llama al metodo
correspondiente
en el objeto
remote
Registry
object
client
metodo(parametros)
Hello stub = (Hello) UnicastRemoteObject.exportObject(obj, 0);
object
server
resultado
El objeto stub se genera en el servidor, tiene la dirección
IP y puerto del servidor codificada:
Para que el cliente obtenga el Stub:
Crea conexiones, crea mensajes de
invocación remota, envia y recibe
mensajes, se comunica con stub y
skeleton.
stub
skeleton
remote reference layer
remote reference layer
transport layer
transport layer
Se puede copiar manualmente el fichero (en Java 1.4)
Se carga dinamicamente desde la direccion URL indicada por el
registro RMI (anotada en el objeto a través de la propiedad
java.rmi.server.codebase con la que se ejecuta el servidor)
remote object
Conexión Sockets, (u otros
datagramas, multicast)
object
Registry RMI
Remote interface
logical data path
{
Cliente RMI
physical data path
object
m1
m2
m3
Servidor RMI
Stub.class
9
10
Servidor Ficheros / Web /..
Registro RMI
Implementación del Servidor RMI
client
De manera transparente al programador:
Cuando se arranca el servidor, comienza a escuchar en
un puerto a la espera de peticiones de clientes. (puerto
no fijo, el registro RMI dira al cliente cual es ese puerto).
Los servidores deben de ser concurrentes, cada petición
debe resolverse en un hilo.
Multiples clientes pueden llamar concurrentemente al mismo
procedimiento / objecto remoto, las implementaciones
deben de tenerlo en cuenta.
El cliente no crea objetos remotos (new de JAVA), para crear
objetos remotos habria que utilizar un patrón factoria
(ver http://java.sun.com/j2se/1.5.0/docs/guide/rmi/Factory.html )
11
Los registros RMI son servidores que se
pueden arrancar de dos maneras:
Desde linea de comandos
% rmiregistry
<port number>
Desde un programa servidor:
registro
server
Registrar(objecto)
localizar(nombre)
Ref. Objeto
Objecto.metodo()
import java.rmi.registry.LocateRegistry;
LocateRegistry.createRegistry (1099 );
La clase Naming provee metodos para acceder a un registro RMI y registrar
objectos, localizar objectos, listar objectos o desregistrarlos.
void bind (String name, Remote obj)
El servidor registra un objeto con nombre name.
void unbind (String name, Remote obj)
Remote lookup(String name)
El servidor desregistra un objecto.
El cliente localiza un objecto por su nombre.
Los nombres son del tipo:
String registryURL = "rmi://localhost:" + portNum + "/someName";
12
Otros Procedimientos Remotos
En C:
Interfaces Remotos (I)
procedimientos remotos RPC,…
Independientes de lenguaje:
CORBA
(orientado a objetos)
Servicios Web, REST (basados en Web: XML….)
Conceptos comunes:
Remoto
Registros
Servidor Remoto
Representacion Externa de Datos
Data Marshalling
Los programas locales necesitan saber como
llamar a los procedimientos remotos (nombre de
procedimiento, número y tipo de datos de
parametros).
Es necesario que los interfaces de los métodos
remotos sean conocidos por los programas locales.
Interface
remote interface
{
Los interfaces se pueden definir de
varias
maneras,
pej.
como
interfaces Java.
Existen lenguajes de definición de
interfaces IDL que permiten definir
el interface de un procedimiento
remoto independientemente del
lenguaje de programación.
Por lo tanto la implementación de un
procedimiento remoto puede estar en
un lenguage diferente al programa
local: cliente en JAVA y servidor en C.
implementation
of methods
13
Interfaces Remotos (II)
Method(para1,para2)
Method2(param)
Method3(param3)
// file: SomeInterface.java
import java.rmi.*
public interface SomeInterface extends
Remote {
public String someMethod1( )
throws java.rmi.RemoteException;
public int someMethod2( float )
throws java.rmi.RemoteException;
// file Person.idl
struct Person {
string name;
string place;
long year;
};
interface PersonList {
readonly attribute string
listname;
void addPerson(in Person p) ;
void getPerson(in string name,
out Person p);
long number();
};
15
14
Procedimientos remotos vs. objetos
distribuidos
En lenguajes no orientados a objetos se implementan
procedimientos remotos: las aplicaciones locales
invocan procedimientos remotos. Ejemplo RPC.
Los interfaces definen los procedimientos exportados.
Existe un registro para localizar máquinas que proveean
procedimientos remotos.
Los clientes llaman a los procedimientos remotos como si
fueran locales.
En lenguajes orientados a objetos se implementa
objectos distribuidos: los objetos locales invocan
metodos de objectos remotos. Ejemplo RMI.
Los interfaces definen las clases de los objectos que exportan
metodos.
Existe un registro para localizar los objectos remotos.
Los clientes llaman a los metodos de los objectos remotos
como si fueran locales.
16
Servidor de métodos remoto
Registros
El servidor implementa los procedimientos/objetos que se
especifican en el interface.
Por cada procedimiento/objeto precisa un skeleton.
El servidor tiene que registrar los procedimientos/metodos en un
registro: dinamicamente al iniciarse (RMI), o en archivo de
configuración (RPC).
De manera transparente al programador:
Cuando se arranca el servidor, comienza a escuchar en un
puerto a la espera de peticiones de clientes.
Los servidores deben de ser concurrentes, cada petición debe
resolverse en una proceso/hilo.
Multiples clientes pueden llamar concurrentemente al mismo
procedimiento / objecto remoto, las implementaciones deben de
tenerlo en cuenta.
17
stub
skeleton
Remote
Method
Invoke Remote Method
marshal parameters;
send Request
Unmarshal parameters;
Invoke method execute code
and return a
value
receive return value;
marshal reply;
send reply
Unmarshall reply;
return value
receive return value
client
registro
server
Registrar(metodo)
localizar(metodo)
server, port, ..
metodo()
18
Data marshalling
Secuencia procedimientos remotos
Local
Method
Los programas que necesitan
invocar un procedimiento remoto,
clientes, tienen que localizarlo a
través de un registro (de igual
manera que los clientes de Web
utilizan el DNS para localizar
servidores).
Los programas que permiten ser
invocados remotamente tienen que
registrarse en un registro.
El
registro
es
un
servicio
independiente que mapea nombres
de procedimientos u objetos con su
implementación remota.
19
Los parametros de entrada
y
salida
de
un
procedimiento remoto se
deben de enviar en su
totalidad (no es posible
pasar referencias!!).
Diferentes
ordenadores
pueden tener diferente
representación
interna
para el mismo tipo de
datos, por lo tanto una
representación
externa
debe de ser acordada.
Data marshalling es el
proceso de (I) aplanar la
estructura de datos, y (ii)
convertir los datos a una
representación externa.
"This is a test."
host A
1.2
marshalling
1.
2.
7.3
-1.5
Aplanar estructura datos
Convertir a
representación externa
110011 ... 10000100 ...
RED
110011 ... 10000100 ..
unmarshalling
"This is a test."
1. Convertir datos a
representación interna
2. Crear estructuras de datos
-1.5
7.3
1.2
host B
20
Serialización Objetos JAVA (I)
Representación Externa de Datos
Binario vs. Ascii
Representación externa de HTTP, TELNET
“GET /index.html HTTP/1.0”
Representación externa de ficheros en FTP
10101111000011111011010110
Para transmitir estructuras de datos complejas en procedimientos
remotos se utilizan:
XML (Extensible Markup Language): ascii
Serialización JAVA: ascii
Sun XDR, ASN.1 (Abstract Syntax Notation): binario
XML es analogo a HTML. Pero las tags tienen significado. Ejemplo:
<person id="123456789">
<name>Smith</name>
<place>London</place>
<year>1934</year>
</person >
Objetos JAVA se pueden aplanar en una estructura
lineal que es adecuada para transmitirlos por la red, o
para guardarlos en ficheros.
Es necesario incluir información sobre la clase del
objecto para que se pueda utilizar cuando se deserialice.
Person p = new Person (“Smith”, “ London”, 1934);
Explicación
Valores serializados
Persona Número de versión de 8-bytes
3
int año
1934
5 Pérez
java.lang.String
nombre:
6 Madrid
a0
java.lang.String
lugar:
a1
Nombre clase, numero versión
Número, tipo y nombre de las
variables de instancia
Valores de las variables de
instancia
21
22
Serialización Objetos JAVA (II)
•Para serializar una
clase tiene que
implementar el
interface Serializable,
que no tiene ningún
método.
•Los objetos
serializables se
pueden guardar en
ficheros, o enviar por
la red.
•No todas las clases
pueden serializarse,
pej. Thread, Socket,…
Procedimientos remotos vs.
paso mensajes (sockets)
// file: PersistentPerson.java
import java..io.Serializable;
public class PersistentPerson implements Serializable {
…………………..
}
Implementar con mensajes procedimientos
remotos requeriria complejos mecanismos
en servidor y clientes.
Paradigma de procedimientos remotos
intenta ocultar esa complejidad.
Paradigma de procedimientos remotos
facilita la programación de aplicaciones
distribuidas ofreciendo API conocido.
(pero, los sockets son más eficientes).
PersistentPerson person = new PersistentPerson();
FileOutputStream os = new FileOutputStream(“tmp”);
// OutputStream os = dataSocket.getOutputStream();
ObjectOutputStream out = new ObjectOutputStream(os);
out.writeObject(person);
out.close();
FileInputStream is = new FileInputStream(“tmp”);
//InputStream is = mySocket.getInputStream();
ObjectInputStream in = new ObjectInputStream(is);
PersistentPerson person = (PersistentPerson) in.readObject();
in.close();
23
24
Descargar