Ahora si, la capa final. Lo que tiene que hacer esta capa es dar una interfaz amigable con el desarrollador para agregar y consumir servicios. Vimos que la API que daba la capa Pedido no era mala, pero se puede mejorar; tanto que podemos hacer que se parezca mucho a una invocación local. Idealmente queremos que tenga la misma sintaxis y semántica que en una llamada local.
Lo primero que tenemos que hacer es ver como, desde el cliente, nos “enganchamos” al código del servidor. Esto lo vamos a hacer mediante un proxy. Un proxy no es otra cosa que un representante del servicio en el cliente. Entonces, las invocaciones que se hagan sobre el proxy van a terminar en servidor:

Esquema de una llamada RPC
La idea es que este proxy utilice la capa Pedido: construyendo el RequestPacket, mandándolo con send() y devolviendo el ResponsePacket con la respuesta. Y en el servidor hay que tener un RequestPacketListener que “decodifique” el paquete y lo mande a ejecutar al método correcto de la implementación correcta.
Entonces vamos a partir el servicio en dos: interfaz e implementación. La interfaz del servicio la usa el cliente:
public interface MathService {
double getPI();
}
Y su implementación está en el servidor:
public class MathServiceImpl implements MathService {
@Override
public double getPI() {
return 3.1416;
}
}
El hecho de que MathServiceImpl implemente MathService, es por prolijidad, pero no es obligatorio.
Ahora necesitamos una implementación del lado del cliente que utilice la capa Pedido:
public class MathServiceProxy implements MathService {
@Override
public double getPI() {
RequestPacket req = new RequestPacket(id, “obtener_valor_de_pi”);
ResponsePacket resp = requestManager.send(req);
return ((Double)resp.getData()).doubleValue();
}
}
Y en el servidor:
public class RemoteExecution implements RequestPacketListener {
public ResponsePacket requestPacketArrived(RequestPacket requestPacket) {
if (requestPacket.getPayload().equals(“obtener_valor_de_pi”)) {
return new ResponsePacket(requestPacket.getKey(), mathServiceImpl.getPI());
}
return null;
}
}
Para realizar la invocación desde el cliente:
MathService mathService = new MathServiceProxy(); double pi = mathService.getPI();
Así invocamos desde el cliente, utilizando la interfaz, al servidor y obtenemos la respuesta. La capa Servicio nos va a dar todo esto (y más) automágicamente. Esto nos va a permitir que solamente tengamos que escribir la interfaz (MathService) y la implementación del servicio (MathServiceImpl).
Las preguntas que quedan son:
-
En el cliente: ¿Cómo vamos a hacer para crear una instancia que sea un proxy de la clase MathServiceImpl, que implemente la interfaz MathService en forma automática y en tiempo de ejecución?
-
En el servidor: ¿Cómo vamos a hacer un RequestListener genérico que “decodifique” el RequestPacket en invoque al método correcto de MathService?
Estas dos preguntas las vamos a responder en el próximo artículo
