Vous êtes sur la page 1sur 9

Faculté des Sciences de Tunis

Département des Sciences de l'Informatique

Systèmes Distribués
Mini-Projet de Programmation RMI

Réalisé Par :
Hamdi KADRI
LFI3 Amphi B Grp 2

Aymen MAHMOUDI
LFI3 Amphi B Grp 3

Année Universitaire 2009 – 2010


1 Présentation :
Notre projet consiste à créer une application qui se compose de trois parties :
● Un serveur pour permettre la réservation par une Chaîne Hôtellière
● Un serveur pour permettre la réservation pour une Companie de Aérienne
● Un client qui peut se connecter et utiliser les deux serveurs mentinnés ci-dessus pour la réservation.
Nous avons développé cette application avec l'IDE open source NetBeans 6.7 et cette application existe
sous forme d'un fichier Jar (Java Archive). La suite explique en plus de détails techniques la démarche, les
contraintes et la philosophie de l'applications.

Fig 1 : Développement de l'application sous NetBeans 6.7


2 Conception et Développement de l'application :
Notre idée était de créer une seule application pour les trois companies : elle s'exécute selon le cas
d'utilisation : (la casse compte pour les arguments)
1. Pour la companie aérienne, on lance le serveur par : java -jar TPSR.jar FlightServer
2. Pour la chaîne hôtellière, on utilisera : java -jar TPSR.jar HotelServer
3. Pour l'agence : java -jar TPSR.jar AgencyClient
Ce qui nous mène à une fonction main de ce type :
Listing 1: La Classe Main.java
/**
*
* @author Hamdi Kadri Amphi B Gr 2
* @author Aymen Mahmoudi Amphi B Gr 3
*/
package tpsr;
import java.rmi.Naming;
public static void main(String[] args) {
if(args[0].equals("HotelServer")){
try{
HotelServer hs = new HotelServer();
Naming.rebind("HotelServer", hs);
}catch(Exception e){e.printStackTrace();}
}

if(args[0].equals("FlightServer")){
try{
FlightServer fs = new FlightServer();
Naming.rebind("FlightServer", fs);
}catch(Exception e){e.printStackTrace();}
}

if(args[0].equals("AgencyClient")){
AgencyReservationApp arapp = new tpsr.AgencyReservationApp();
arapp.setLocationRelativeTo(null);//center the frame
arapp.setAlwaysOnTop(true);//toujours au dessus des autres applications
arapp.setVisible(true);//maintenant on voit l'interface
}
}

Ainsi trois classes vont faire l'affaire ici : AgencyReservationApp, HotelServer et FlightServer.
Avec l'instruction Naming.rebind(... , ...) nous allons rendre accessibles sur le réseau les objets distants qui
sont les serveurs.
Nous allons supposer que les bases de données sont organisées ainsi :
● Pour la companie aérienne :
○ allflights : base de données qui contient tous les vols, et pour chaque vol son numéro, source,
destination, date et nombre des places encore vides.
○ flight_xxx (xxx est un nombre) : base qu'on peut déduire de allflights et qui contient la liste des
clients, leur numéros de tickets...
● Pour la chaîne hôtellière :
○ la première appelée nomhotel1 contient les chambres vides + les dates
○ la deuxième appelée nomhotel2 contient les réservations (client, date, nombre de chambre)
Pour la liste des hôtels on a supposé qu'elle soit connue :
Listing 2 : Liste prédéfinie des Hotels.
/*Extrait de dbHotel.java*/
String[] hotels = {"Hilton", "Sheraton", "Henry IV", "Golden Tulip", "Hotelx", "Hotely"};

Les deux serveurs auront accès aux bases de données sur la machine locale et le client de l'agence va
exécuter ses fonctions de loin (c'est déjà ce que veut dire Remote) et récupérer les résultats. Donc on doit
dévbelopper les interfaces qui seront importantes pour cette communication à distance à travers le réseau :
Listing 3 : Interfaces :
/*Extrait de HotelServerInterface.java*/
package tpsr;

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface HotelServerInterface extends Remote{


int reserve(String name, String hotelName, String date, int room) throws
RemoteException;
int cancel( int reservation) throws RemoteException;
String list(int reservation) throws RemoteException;
}

/*Extrait de FlightCompanyServerInterface.java*/
package tpsr;

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface FlightCompanyServerInterface extends Remote{


int reserve(String name, int flight, String date) throws RemoteException;
int cancel(int flight, int ticket) throws RemoteException;
String list(String date, String departureCountry, String arrivalCountry) throws
RemoteException;
}
Nos serveurs doivent maintenant implémenter ces interfaces et définir le corps des méthodes déclarées. Le
suivant listing contient par exemple le code nécessaire pour implémenter la réservation d'un vol :
Listing 4 :

/*Extrait de FlightServer.java*/
public class FlightServer extends UnicastRemoteObject implements
FlightCompanyServerInterface {
dbFlight dbf = new dbFlight();
/*cette classe sera le gestionnaire de la BD des vols*/
....

public int reserve(String name, int flight, String date) {

if (dbf.listFreeSeats(flight) > 0) {
return (dbf.reserve(name, flight, date));
}
else return -1;
}

...
}

/*Extrait de dbFlight.java*/
int listFreeSeats(int flight) {
try {
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT * FROM allflights WHERE ID=" +
flight);
return(rs.getInt("available_seats"));
} catch (Exception e) {
e.printStackTrace();
}
return -1;
}

int reserve(String name, int flight, String date) {


int ticketnumber = -1;
try {
Statement st = conn.createStatement();
ResultSet rs = st.executeQuery("SELECT * FROM flight_" + flight + "WHERE
last='yes'");
ticketnumber = rs.getInt("ticketnumber");
st.executeQuery("UPDATE flight_" + flight + "SET last=no WHERE last=yes");
st.executeQuery("INSERT INTO flight_" + flight + " (name, date, last,
ticketnumber) " + name + " " + date + " yes " + ticketnumber + 1);
} catch (Exception e) {
e.printStackTrace();
}
return (ticketnumber);
}

On procède de cette façon pour les deux serveurs. Maintenant qu'ils sont prêts, Il ne nous reste que le
client qui va tout contrôler. Nous avons opté pour un client graphique nous avons utilisé le constructeur
d'interfaces de NetBeans et la bibliothèque swing pour le faire. Voici à quoi ressemble notre interface
graphique :
Fig. 2 : L'interface graphique finale.

Nous avons bien veillé à produire une interface simple, bien compréhensible et ordonnée en utilisant les
JPanels. Nous avons estimé qu'avec NetBeans le temps du développement de l'interface graphique n'excède
pas 10% du temps consacré au développement de toute l'application.

La création est au mode glisser-déposer (drag and drop) donc très facile, mais la gestion des événements
est la tâche qui importe : voici ce qui se passe lorsque l'utilisateur appuie sur le bouton Submit de la
réservation des vols :
Listing 4 :

package tpsr;
import java.rmi.Naming;
public class AgencyReservationApp extends javax.swing.JFrame {

FlightServer fs;
HotelServer hs;

/** Creates new form AgencyReservationApp */


public AgencyReservationApp() {
initComponents();
try {
fs = (tpsr.FlightServer) Naming.lookup("rmi://FlightCompanyURL/FlightServer");
hs = (tpsr.HotelServer) Naming.lookup("rmi://HotelsURL/HotleServer");
} catch (Exception e) {
e.printStackTrace();
dispose();
}

...

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {


int ticket = fs.reserve(jTextField1.getText(),
Integer.parseInt(jTextField2.getText()), jTextField3.getText());
if( ticket == -1)
javax.swing.JOptionPane.showMessageDialog(null, "Failure !");
else javax.swing.JOptionPane.showMessageDialog(null, "Ticket n° " +ticket);
}

...

Le code souligné révèle comment peut-on se connecter à nos objet via une connexion rmi fournies par
Java.

Maintenant que nous avons terminé notre application, on la compile, on corrige les fautes éventuelles
(NetBeans offre une aide précieuse là-dessus) et lorsque tout va bien, on fait le build. Nous obtenons un
fichier TPSR.jar dans les dossier dist de notre projet : c'est l'application qu'on a déjà développée !

On peut lancer notre application de l'IDE, mais le Terminal nous le permet aussi. Voici comment lancer
l'application depuis un Terminal Linux :
Et voici le contenu final de notre espace de travail :
3 Ressources et outils :

● Outils :
○ Java Development Kit 1.6.0_06 (l'exécution de l'application demandera un JRE de cette version
ou plus neuve)
○ NetBeans IDE 6.7 Linux i386 Version (www.netbeans.org)
○ OpenOffice.Org version 2.4.0 pour Linux OpenSUSE 11.0
○ KsnapShot pour KDE 3.5.1
● Ressources :
○ Bruce Eckels, Thinking in Java, Second Edition
○ Java Documentation (Sun MicroSystems)
○ Rogers Cadenhead & Laura Lemay : Sams Teach Yourself Java In 21 Days