RMI - JAVA
Introdução
Introdução á Computação Distribuída com RMI
A tecnologia RMI - Remote Method Invocation (Invocação de Métodos
Remotos) foi primeiramente introduzida no Java, no JDK versão 1.1, elevando
a programação para redes em um patamar mais elevado. Apesar do RMI ser
relativamente fácil, ele põe o desenvolvedor Java frente à um novo
paradigma, o mundo da computação de objetos distribuídos.
Onde o desenvolvedor ou equipe de desenvolvimento terá a
necessidade de criar um paradigma de distribuição dos métodos e uma boa
abordagem dos mesmos.
Objetivo
O principal objetivo para os criadores do RMI, é que programadores
desenvolvam seus sistemas do mesmo modo que desenvolviam antes porem
sendo possível utilizá-los como sistemas distribuídos.
Para que isso ocorresse ele tiveram que mapear cuidadosamente as
classes e objetos do Java em JVM(Java Virtual Machine), afim que os
mesmos sejam implementados em sistemas distribuídos como múltiplas
JVMS.
Os criadores tiveram o trabalho de simular que essas classes e
objetos trabalhassem separadamente mas de que pra os processos fossem
localmente, ou seja uma classe e seus métodos estariam em outra maquina
diferente da que estou porem isso seria indiferente para meu processo pois
para o mesmo tudo estaria loca.
Interfaces: O coração do RMI
A arquitetura RMI é baseada em um importante princípio: a definição do
comportamento e a implementação do comportamento são conceitos separados.
RMI permite que o código que define o comportamento e o código que implementa
o comportamento permanecerem separados e rodarem em JVMs separadas.
Em RMI, a definição do serviço remoto é codificada usando uma interface
Java.
A implementação do serviço remoto é codificada em uma classe. Logo, a
chave para se entender o RMI é lembrar que as interfaces definem o comportamento
e as classes definem a implementação. A classe que implementa o comportamento
roda do lado do servidor RMI. A classe que roda no cliente atua como um Proxy para
o serviço remoto. Veja o seguinte diagrama: O programa cliente faz chamadas de
métodos pelo objeto Proxy, o RMI envia a requisição para a JVM remota e redireciona
para a implementação. Qualquer valor retornado pela implementação é devolvido ao
Arquitetura de Camadas do RMI
Com o entendimento da arquitetura RMI num alto nível, vamos dar uma breve olhada na sua
implementação. A implementação do RMI é essencialmente feita de três camadas de abstração.
1º A camada Stub e Skeleton está abaixo dos olhos do desenvolvedor. Esta camada intercepta as
chamadas de métodos feitas pelo cliente para que a variável de referência da interface redirecione
essas chamadas para o serviço RMI remoto.
2º A próxima camada é a Remote Reference Layer. Esta camada sabe como interpretar e gerencias
referências feitas dos clientes para os objetos do serviço remoto. A conexão do cliente ao servidor é
Unicast (uma-para-um).
3º A camada de transporte é baseada nas conexões TCP/IP entre as maquinas em uma rede. Usando
essa arquitetura de camadas, cada uma das camadas poderia ser facilmente melhorada ou substituída
sem afetar o resto do sistema. Por exemplo, a camada de transporte poderia ser substituída por uma
camada que implemente conexões UDP/IP, sem afetar as camadas superiores.
Neste exemplo mostro melhor como
Funciona.
Nomeando Objetos Remotos
Como um cliente acha o serviço remoto RMI?
Os clientes acham os serviços remotos usando o serviço de nomeação ou diretório
(naming or directory). Isso parece um pouco redundante, mas o serviço de nomeação ou
diretório roda como um endereço bem formado (host:port).
O RMI pode usar diferentes tipos de serviços de diretório, incluindo o JNDI. O próprio
RMI inclue um simples serviço, chamado de RMI Registry. O RMI Registry roda em cada maquina
que hospeda o serviço remoto, por definição na porta 1099.
Numa máquina host, um programa servidor cria um serviço remoto, primeiramente
criando o objeto que implemente aquele serviço. Em seguida ele exporta aquele objeto para o
RMI. Quando o objeto é exportado o RMI cria um serviço que aguarda as conexões do cliente. O
servidor registra o objeto no RMI Registry, com um nome público. No lado do cliente o RMI
Registry é acessado através da classe estática Naming.
Ela provém o método lookup( ), que o cliente usa para requisitar o registro. Esse
método aceita a URL que especifica o nome do servidor e o nome do serviço desejado. O
método retorna uma referência remota para o objeto do serviço.
A URL é formada como seguinte: view plainprint?
rmi://<host_name>[:port_number]/<service_name>
rmi://<host_name>[:port_number]/<service_name>
Elementos do RMI
Arquitetura de Camadas do RMI
Cliente.
Qualquer programa JAVA pode ser um potencial cliente, contanto que ele possua acesso as classes e
objetos mínimos necessários e obtenha a referencia do objeto registrado.
Stub.
Este é o responsável por qualquer comunicação com o objeto distuibuido através do skeleton. O stub
transforma as chamadas locais do cliente em chamadas no objeto remoto, e também é responsável por traduzir a
chamada remota para o formato esperado pela chamada local. Sendo assim o mesmo se assemelha ao Maximo a
programação usual.
Skeleton.
O skeleton tem o papel semelhante a o stub, porem no lado do servidor. O mesmo é responsável por
receber as requisições do cliente e traduzi-las para o servidor de forma análoga e devolve-la para o stub
posteriormente.
Camadas de referência.
Responsável pela criação e gerenciamento de referencias aos objetos remotos.
Ele basicamente converte as solicitações RMI para a camada de transporte que esta sendo utilizada.
Camadas de transporte.
Prove a comunicação em rede entre as jvms, usa os sokets default (tcp) ou outro tipo pode ser utilizado.
Usando o RMI
Criando um aplicativo simples, cliente e servidor, que executa métodos do objeto remoto. Para tanto
não necessitamos de duas máquinas distintas ou com IP distintos. O exemplo pode ser rodado na
mesma máquina, pois o RMI sabe como trabalhar com isso, mesmo que o host e o cliente sejam na
mesma localidade. Um sistema RMI é composto de várias partes: Definição das interfaces para os
serviços remotos
Mostrarei como criar um sistema que implemente o RMI, utilizando-se de um programa
cliente e um programa servidor. Não utilizaremos um servidor FTP ou HTTP, no entanto utilizaremos os
programas na mesma máquina e uma mesma estrutura de diretórios. Os passos a serem seguidos
agora são: Escrever e compilar o código Java da interface
1º - Escrever e compilar o código Java das implementações das classes
2º - Gerar as classes Stub e Skeleton das classes de implementação Crie um diretório para salvar todos
os seus arquivos de projeto. Você pode fazer o download do código fonte usado nesse tutorial.
3º - Escrever e compilar o código Java das implementações das classes
4º - Gerar as classes Stub e Skeleton das classes de implementação Crie um diretório para salvar todos
os seus arquivos de projeto. Você pode fazer o download do código fonte usado nesse tutorial.
Interfaces
O primeiro passo, como dito, será criar a interface e compilá-la. A interface define todas as
funcionalidades remotas oferecidas pelo serviço. Nomeio o arquivo como: Mensageiro.java.
view plainprint?
1. import java.rmi.Remote;
2. import java.rmi.RemoteException;
3.
4. public interface Mensageiro extends Remote {
5.
6. public void enviarMensagem( String msg ) throws RemoteException;
7. public String lerMensagem() throws RemoteException;
8. }
Perceba que esta interface estende a classe Remote, e cada assinatura de método declara as
funcionalidades do serviço, e que podem gerar uma exceção RemoteException. Salve este arquivo
(Mensageiro.java) no seu diretório e compile, com a seguinte linha de comando:
view plainprint?
Implementação
Download

RMI - JAVA