1. TP2 : THE REMOTE METHOD INVOCATION PERIODE 4
MARIEM ZAOUALI | ESPRIMS 1
TP2 : The Remote Method Invocation
Problème
Dans ce TP, on veut simuler une application de consultation et réservation de
places dans un spectacle.
Le client demandera au serveur le nombre de places disponibles pour un
certain spectacle qu’il choisit d’une liste. Le serveur lui répond en lui affichant le
nombre de places restants. Si les places sont encore disponibles, le client peut passer
la commande de réservation, sinon on lui affiche de nouveau, la liste des spectacles.
Pour réaliser cette application, on demande d’implémenter les différents
échanges entre le client et serveur en respectant les étapes d’invocation de méthode
à distance en utilisant le Java RMI, l’implémentation SUN du RPC.
Un exemple d’échauffement 1
Dans cette première partie, on va simuler RMI (à appliquer après dans le contexte
de l’application de consultation et réservation de places pour spectacles).
Vous allez créer deux projets comme indiqué dans la Figure 1 et dont le contenu est
le suivant :
Figure 1 L'arborescence à créer
1. JavaRMI_client : contenant une classe RMIClient.java et une interface
RMIServerIntf.java dont le contenu est le suivant :
package tn.esprims.client;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
2. TP2 : THE REMOTE METHOD INVOCATION PERIODE 4
MARIEM ZAOUALI | ESPRIMS 2
public class RMIClient {
public static void main(String args[]) throws Exception {
Registry registry = LocateRegistry.getRegistry("localhost");
RMIServerIntf obj = (RMIServerIntf) registry.lookup("RMIServer");
System.out.println(obj.getMessage());
}
}
package tn.esprims.client;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface RMIServerIntf extends Remote {
public String getMessage() throws RemoteException;
}
2. JavaRMI_serveur : JavaRMI_serveur : contenant une classe RMIServer.java et
une interface RMIServerIntf.java dont le contenu est le suivant :
package tn.esprims.serveur;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
public class RMIServer
implements RMIServerIntf {
public static final String MESSAGE = "Hello world";
public RMIServer() throws RemoteException {
}
public String getMessage() throws RemoteException {
return MESSAGE;
}
public static void main(String args[]) throws Exception {
System.out.println("RMI server started");
//Instantiate RmiServer
RMIServer obj = new RMIServer();
try { //special exception handler for registry creation
RMIServerIntf stub = (RMIServerIntf)
UnicastRemoteObject.exportObject(obj,0);
Registry reg;
3. TP2 : THE REMOTE METHOD INVOCATION PERIODE 4
MARIEM ZAOUALI | ESPRIMS 3
try {
reg = LocateRegistry.createRegistry(1099);
System.out.println("java RMI registry created.");
} catch(Exception e) {
System.out.println("Using existing registry");
reg = LocateRegistry.getRegistry();
}
reg.rebind("RMIServer", stub);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
package tn.esprims.serveur;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface RMIServerIntf extends Remote {
public String getMessage() throws RemoteException;
}
Exécution de l’exemple d’échauffement 1
Vous lancez tout d’abord le serveur qui va créer un registry où il enregistre l’objet
RMIServer dans le registry. Vous lancez ensuite le client qui cherchera l’objet.
NB : Auparavant, on génère nous-même le stub et skeleton. Depuis le JDK 1.5, cette
génération se fait automatiquement.
La Figure 2 montre le schéma d’ensemble de cette exécution.
Figure 2 Etape d'exécution d'une application à base de RMI
4. TP2 : THE REMOTE METHOD INVOCATION PERIODE 4
MARIEM ZAOUALI | ESPRIMS 4
Un exemple d’échauffement 2
Maintenant, il est question d’envoyer un objet vers le Serveur comme paramètre à la
méthode distante. Il faut suivre les étapes sinon vous auriez des erreurs :
1. Nommer les packages du côté client et serveur de la même manière
2. Implémenter l’interface Serializable des deux côtés (client et serveur) de
l’objet que vous voulez envoyer
La Figure 3 montre l’arborescence à réaliser :
Figure 3 Arborescence à créer
Dans le projet JavaRMI_client :
package tn.esprims;
import java.io.Serializable;
public class MessageInfo implements Serializable {
public static final long serialVersionUID = 52L;
public int totalMessages;
public int messageNum;
public MessageInfo(int total, int msgNum) {
totalMessages = total;
messageNum = msgNum;
}
}
5. TP2 : THE REMOTE METHOD INVOCATION PERIODE 4
MARIEM ZAOUALI | ESPRIMS 5
package tn.esprims;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class RMIClient {
public static void main(String args[]) throws Exception {
Registry registry = LocateRegistry.getRegistry("localhost");
RMIServerIntf obj = (RMIServerIntf) registry.lookup("RMIServer");
MessageInfo v= new MessageInfo(1,10);
System.out.println(obj.getMessage(v));
}
}
package tn.esprims;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface RMIServerIntf extends Remote {
public String getMessage(MessageInfo m) throws RemoteException;
}
Dans le projet JavaRMI_serveur :
package tn.esprims;
import java.io.Serializable;
import java.rmi.RemoteException;
public class MessageInfo implements Serializable {
public static final long serialVersionUID = 52L;
public int totalMessages;
public int messageNum;
public MessageInfo(int total, int msgNum) {
totalMessages = total;
messageNum = msgNum;
}
public String toString(){
return new String("C'est un traitement chez le serveur que vous croyez
qu'il se fait en local chez le client "+totalMessages+";"+messageNum+"n");
}
}
package tn.esprims;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
6. TP2 : THE REMOTE METHOD INVOCATION PERIODE 4
MARIEM ZAOUALI | ESPRIMS 6
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;
public class RMIServer
implements RMIServerIntf {
public static final String MESSAGE = "Hello world";
public RMIServer() throws RemoteException {
}
public String getMessage(MessageInfo v) throws RemoteException {
return v.toString();
}
public static void main(String args[]) throws Exception {
System.out.println("RMI server started");
//Instantiate RmiServer
RMIServer obj = new RMIServer();
try { //special exception handler for registry creation
RMIServerIntf stub = (RMIServerIntf)
UnicastRemoteObject.exportObject(obj,0);
Registry reg;
try {
reg = LocateRegistry.createRegistry(1099);
System.out.println("java RMI registry created.");
} catch(Exception e) {
System.out.println("Using existing registry");
reg = LocateRegistry.getRegistry();
}
reg.rebind("RMIServer", stub);
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
package tn.esprims;
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface RMIServerIntf extends Remote {
7. TP2 : THE REMOTE METHOD INVOCATION PERIODE 4
MARIEM ZAOUALI | ESPRIMS 7
public String getMessage(MessageInfo m) throws RemoteException;
}
Réalisation de la partie serveur du Gestionnaire du Spectacle
1. Ecrire une interface « distante » InterfaceSpectacle qui définit deux
méthodes et qui étend java.rmi.Remote :
a. int consulter (int entier) : Cette méthode permet de passer en
paramètre le ID de spectacle au serveur et de retourner le
nombre de places disponibles.
b. String reserver(int entier) : Cette méthode permet de passer en
paramètre le ID de spectacle et de retourner un message
« succès » si la réservation est réussie, « échec » sinon.
2. Ecrire la classe GestionnaireSpectacle qui réalise les tâches de
l’interface précédente et qui étend la classe
java.rmi.server.UnicastRemoteObject. Dans cette classe, ajoutez un
ArrayList comme variable static et globale contenant tous les
spectacles que le serveur propose.
3. Ecrire une classe Enregistrement qui possède une méthode main qui
enregistre l’objet GestionnaireSpectacle dans le registre.
Réalisation de la partie client du Gestionnaire du Spectacle
Il est à vous maintenant de compléter le TP en créant les classes et les interfaces
nécessaires. Vous devez sérialiser votre objet à envoyer par RMI.