Documentação
-
Capítulo 5.5 Java RMI do livro principal da cadeira
(Coulouris, "Distributed Systems: Concepts and Design")
Enunciado
Partindo de um Jogo do Galo (Tic Tac Toe) feito para um cenário local,
pretende-se desenvolver uma variante do jogo onde a parte
computacionalmente mais pesada é realizada por um servidor remoto.
O servidor guarda as variáveis do jogo.
O cliente faz a interface com o utilizador.
Sugestão: nas alíneas seguintes, corra os programas cliente e servidor
numa máquina não partilhada com outros grupos para evitar conflitos.
Use uma máquina pessoal ou do laboratório e não o sigma.
-
Descarregue e descomprima o código fonte da aplicação
Jogo do Galo/Tic Tac Toe
(servidor,
cliente).
-
Importe os projectos no Eclipse, recorrendo a File > Import > Maven > Existing Maven Projects.
-
No ponto de partida o código está todo centralizado no servidor, estando o cliente vazio.
- Estude os principais ficheiros com a implementação do jogo
(Game.java e TTT.java).
-
Compile e experimente o jogo na sua versão centralizada
(executando mvn compile exec:java).
-
Pretende-se que a classe TTT.java, que implementa o jogo,
passe a ser invocável remotamente.
Dessa forma,
permitir-se-á que haja um cliente remoto
(que possivelmente corre em máquina diferente que a máquina que serve o jogo)
que interage com os jogadores e que invoca as funções do servidor via
Java RMI (Remote Method Invocation).
-
Comece por desenhar os métodos remotos do servidor numa
interface chamada TTTService.
A interface deve expor todas as funções remotas que o cliente precisa de invocar.
Para ser uma interface remota, precisa também de herdar de java.rmi.Remote e
cada um dos seus métodos deve lançar uma java.rmi.RemoteException.
Consulte o exemplo de interface remota apresentado no livro para ajuda.
-
Coloque a nova interface num módulo
interface
-
Depois de codificar a interface,
compile o código e instale a dependência:
cd ttt-rmi-interface
mvn install
-
Adicione a dependência no pom.xml do servidor e do cliente,
pois esta interface terá que ser partilhada por ambos.
...
<dependency>
<groupId>example</groupId>
<artifactId>ttt-rmi-interface</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
...
-
Depois de editar os pom.xml, refresque as dependências do Maven no projeto Eclipse
(right-click, Maven, Update Project..., Force Update of Snapshots/Releases, OK)
-
No servidor, transforme a classe TTT para que passe a
implementar a interface remota TTTService.
Para que instâncias desta classe possam ser objectos remotos,
modifique a definição da classe TTT para que ela passe a herdar de
java.rmi.server.UnicastRemoteObject
e acrescente um construtor que lance excepção RemoteException.
Deverá implementar a lógica dos métodos que o Cliente irá chamar posteriormente.
Consulte o exemplo da classe
shapeListServant apresentado no livro para ajuda.
-
No servidor, crie uma nova classe TTTServer com método main,
onde correrá o servidor.
No método main deverá:
-
Instanciar um objecto remoto do tipo TTT
-
Lançar um rmiregistry (serviço de nomes do RMI) e
registar o objecto remoto nesse rmiregistry
Consulte o exemplo da classe
ShapeListServer apresentado no livro para ajuda.
Não se esqueça de actualizar a mainclass do ficheiro pom.xml
de modo a reflectir a classe que possui o método main.
-
Deverá agora proceder à modificação do cliente para chamar remotamente os métodos definidos anteriormente.
-
Mover a classe ttt.Game do servidor para o cliente.
Implemente um cliente remoto que,
com base nos comandos recebidos pela consola local,
invoca métodos do jogo remoto.
Assuma que ambos os jogadores de cada jogo usam o mesmo cliente.
Consulte o exemplo do cliente
apresentado no livro para ajuda.
-
Não se esqueça de, na chamada ao método Naming.lookup,
definir correctamente o URL que localiza o objecto, na forma:
//host:port/name,
em que host e port definem a máquina e o porto
onde corre o rmiregistry onde foi
registado o objecto remoto e name é o nome que foi
atribuído ao objecto pelo servidor quando chamou rebind.
-
Adicione o tratamento adequado às exceções lançadas quando acontece
algo inesperado numa invocação remota.
(Algumas das excepções que podem ocorrer são:
java.rmi.UnknownHostException,
java.rmi.UnmarshalException,
java.rmi.MarshalException,
java.rmi.RemoteException e
java.rmi.ConnectException)
-
Experimente lançar o servidor e depois um cliente para jogar.
-
Responda às seguintes questões:
-
Quando se usa SUN RPC é gerado código para converter os dados de e
para um formato de rede.
O que acontece quando se usa RMI?
-
Das classes e interfaces Java que usou,
quais as que pertencem apenas ao cliente, apenas ao servidor e
a ambos?
O resto do enunciado será entregue na aula.
O objectivo será estender a solução resultante do enunciado acima com mais
procedimentos ou modificar alguns dos seus procedimentos actuais.
Entrega da solução
Fénix, Avaliação, Projetos, mini Exercício 2 - Java RMI
A solução completa deverá ser submetida no Fénix
antes do fim da sua aula de laboratório.
Trabalhos submetidos depois da hora de fim da aula não serão considerados.
Ter atenção ao seguinte:
- Só são aceites trabalhos de estudantes que estiveram
presentes no laboratório.
- Deverá também incluir um ficheiro instrucoes.txt
com resumo da funcionalidade implementada e com instruções para
colocar o programa a funcionar como esperado.
Por exemplo:
- A funcionalidade pedida foi total/parcialmente implementada
...
- O servidor deve executar com o seguinte comando:
mvn install exec:java
- O cliente deve executar com o comando:
mvn compile exec:java
- Assegure-se que a solução é enviada em formato ZIP e que não
contém código compilado (faça mvn clean antes de
comprimir).