2A-SI - Réseaux : Programmation par RPC et JavaRMI Stéphane Vialle Stephane.Vialle@supelec.fr http://www.metz.supelec.fr/~vialle Programmation par RPC et Java-RMI : - Principes des RPC - Utilisation d un IDL - Principes des Java-RMI - Mode opératoire des Java-RMI - Hiérarchie de classes Java - Exemple de client-serveur en Java-RMI - RMI entre plusieurs serveurs 1
Principes des RPC RPC = «Remote Procedure Call» Objectif : appels locaux et distants avec la même syntaxe 1ère version : Birrel & Nelson en 1984 L utilisateur écrit toute l application : le client, le serveur et les mécanismes d envoi et de réception de messages!! Concepts simples, mais complexes à mettre en œuvre Peu utilisé SUN RPC en 1988 Plus simple, Utilise «rpcgen» : génère une partie des fichiers de RPC Utilise le DNS (localisation du serveur : adresse IP) + Portmap (localisation du service : # port) Principes des RPC Appel Service RPC (talon) Protocole de communication 1 Réseau Service RPC Protocole de (talon) communication 2 appel Appelé 3 5 retour 4 retour Client (appelant) Serveur (appelé) 2
Principes des RPC Talon client : stub C est la procédure d interface du site client qui reçoit l appel en mode local le transforme en appel distant en envoyant un message reçoit les résultats après l'exécution retourne les paramètres résultats comme dans un retour de procédure Talon serveur : skeleton C est la procédure sur le site serveur qui reçoit l appel sous forme de message fait réaliser l exécution sur le site serveur par la procédure serveur (choix de la procédure) retransmet les résultats par message Programmation par RPC et Java-RMI : - Principes des RPC - Utilisation d un IDL - Principes des Java-RMI - Mode opératoire des Java-RMI - Hiérarchie de classes Java - Exemple de client-serveur en Java-RMI - RMI entre plusieurs serveurs 3
Utilisation d un IDL Un langage pour la spécification des interfaces entre les clients et les serveurs : Spécification commune au client et au serveur Le «contrat» entre le client et le serveur Définition des types et natures des paramètres IN, OUT, IN-OUT, par valeur, par référence Définition indépendante de la plate-forme Indépendante du langage, de l OS et de la machine Utilisation de ces définitions pour générer automatiquement : Le talon client (ou proxy, ou stub) Le talon serveur (ou squelette, ou skeleton) «projection» dans un langage de programmation Utilisation d un IDL Interface écrite en «IDL» Client Compilateur IDL Serveur Talon coté client (Stub) Talon coté Serveur (Skeleton) Protocole de communication Réseau Protocole de communication 4
Programmation par RPC et Java-RMI : - Principes des RPC - Utilisation d un IDL - Principes des Java-RMI - Mode opératoire des Java-RMI - Hiérarchie de classes Java - Exemple de client-serveur en Java-RMI - RMI entre plusieurs serveurs Principes des Java-RMI Un RPC objet intégré à Java Interaction d'objets situés dans des espaces d'adressage différents sur des machines distinctes Simple à mettre en œuvre : un objet distribué se manipule comme tout autre objet Java Différences RPC/RMI : Il existe un module de localisation sur le host-serveur distant (la rmiregistry) : localisation de chaque objet-serveur. Les RMI sont plus vulnérables aux pannes: impossible de distinguer le cas de panne du serveur d un problème réseau (moins de détails dans les CR d erreurs). Les interfaces (contrats) sont des interfaces Java L IDL est Java lui-même 5
Principes des Java-RMI objet client objet serveur référence appel Talon client Talon serveur état méthode_1() méthode_n() Système de communication Référence d'objet + méthode + arguments Résultat ou exception désignation envoi de requêtes exécution de requête retour de résultat Programmation par RPC et Java-RMI : - Principes des RPC - Utilisation d un IDL - Principes des Java-RMI - Mode opératoire des Java-RMI - Hiérarchie de classes Java - Exemple de client-serveur en Java-RMI - RMI entre plusieurs serveurs 6
Mode opératoire des Java-RMI 0 - A la création de l objet-serveur, un stub et un skeleton (avec un port de communication) sont créés sur le host-serveur 1 - L'objet-serveur s'enregistre auprès du Naming de sa JVM (méthode rebind) 2 - Le Naming enregistre le stub de l objet (sérialisé) auprès du serveur de noms (rmiregistry) 3 - Le serveur de noms est prêt à fournir des références sur l objet-serveur Client Client rmiregistry rmiregistry stub stub Naming Naming stub stub Serveur Serveur JVM Client Skeleton Skeleton JVM Serveur Mode opératoire des Java-RMI 4 - L'objet client fait appel à son Naming pour localiser l'objet-serveur sur l host-serveur (méthode lookup) 5 - Le Naming récupère le stub vers l'objet-serveur auprès de la rmiregistry 6 Le naming installe l objet Stub sur le poste client et retourne sa référence au client 7 - Le client effectue l'appel à l objet serveur par appel à l objet local Stub Client Client Naming Naming rmiregistry rmiregistry stub stub Naming Naming Serveur Serveur Stub Stub Skeleton Skeleton JVM Client JVM Serveur 7
Mode opératoire des Java-RMI Etapes du développement et déploiement : 1. Codage description de l interface du service écriture du code du serveur qui implante l interface écriture du client qui appelle le serveur 2. Compilation génération des stub et skeleton (rmic) compilation des sources (javac) 3. Activation lancement du serveur de noms (rmiregistry) lancement du serveur lancement du client Mode opératoire des Java-RMI Etapes du développement et déploiement : 1 programmation: Interface java Server. java Client. java 2.1 - rmic Server Server_Stub.class Server_Skel.class (2.2 - javac Server.java) Server.class 2.3 - javac Client.java Client.class 3.1 rmiregistry 3.2 java Server 3.3 java Client 8
Programmation par RPC et Java-RMI : - Principes des RPC - Utilisation d un IDL - Principes des Java-RMI - Mode opératoire des Java-RMI - Hiérarchie de classes Java - Exemple de client-serveur en Java-RMI - RMI entre plusieurs serveurs Hiérarchie de classes Java RemoteObject RemoteServer RemoteStubs Activatable Classe : UnicastRemoteObject ActivationGroup_Stub Serveurs Stubs/Skeletons 9
Hiérarchie de classes Java RemoteObject RemoteServer RemoteStubs Activatable Classe : UnicastRemoteObject ActivationGroup_Stub Serveurs démarrés explicitement Objet/Service ayant la durée de vie du processus serveur Pour des comm. P2P entre processus actifs Utilise des comm. TCP Public class MyServerRmi extends UnicastRemoteObject Implements MyInterfaceRmi { Hiérarchie de classes Java RemoteObject RemoteServer RemoteStubs Activatable Classe : UnicastRemoteObject ActivationGroup_Stub Serveurs démarrables par le système Objet/Service persistant (non liés à la durée de vie d un processus) Les constructeurs proposent de définir un port sur lequel sera exporté le service. Sinon un port quelconque sera choisi. 10
Hiérarchie de classes Java RemoteObject RemoteServer RemoteStubs Activatable Classe : UnicastRemoteObject ActivationGroup_Stub Interfaces à destination des classes «stubs»et«skeletons» (les tallons client et serveur générés par rmic) Gérées par le mécanisme des Java-RMI Programmation par RPC et Java-RMI : - Principes des RPC - Utilisation d un IDL - Principes des Java-RMI - Mode opératoire des Java-RMI - Hiérarchie de classes Java - Exemple de client-serveur en Java-RMI - RMI entre plusieurs serveurs 11
Ex. client serveur en Java-RMI Règles d écriture des RMI : Les objets locaux passés en paramètres doivent être (juste) «serializable» Dans la majorité des cas il suffit d ajouter : «extends Serializable» dans l interface de leur classe «implements Serializable» dans la définition de leur classe Rien à faire pour les objets de base (int, double, ) Les objets difficiles à «serialiser» sont les threads éviter de passer des threads en paramètres d appel RMI! Ex. client serveur en Java-RMI Règles d écriture des RMI : Les objets distants ont plus de contraintes : L interface distante doit être publique L interface distante doit étendre l interface java.rmi.remote La classe distante hérite (généralement) de java.rmi.server.unicastremoteobject qui implémente java.rmi.remote (parfait!) Chaque méthode distante doit déclarer au moins l exception java.rmi.remoteexception Les objets distants doivent être déclarés par une référence sur leur interface (uniquement). 12
Ex. client serveur en Java-RMI Client Java rmiregistry Serveur Java «TheServer» Cas simple : Le client connaît le nom du serveur («TheServer») La rmiregistry est lancée sur le serveur Le client passe des arguments «de base» (int) // l'interface à exporter (deux services définis) public interface CalculRmi extends java.rmi.remote { public int plus(int un, int deux) throws java.rmi.remoteexception; public int mult(int un, int deux) throws java.rmi.remoteexception; Ex. client serveur en Java-RMI // Client utilisant des services d un objet-serveur distant import java.rmi.*; public class ClientRmi { static public void main(string arg[]) { int i1, i2, res; String NomHostServeur, NomObjServeur; CalculRmi ObjServeur; // Parse la ligne de commande NomHostServeur = arg[0]; NomObjServeur = arg[1]; i1 = Integer.parseInt(arg[2]); i2 = Integer.parseInt(arg[3]); try { // Recherche de l objet-serveur distant dans la rmiregistry ObjServeur = (CalculRmi) Naming.lookup( "rmi://" + NomHostServeur + "/" + NomObjServeur); // Usage du service distant trouvé res = ObjServeur.plus(i1, i2); catch (Exception e){ System.out.println("Erreur RMI " + e.getmessage()); System.exit(1); System.out.println("Résultat appel RMI: " + res); 13
Ex. client serveur en Java-RMI // Objet-Serveur RMI (debut) import java.util.*; import java.rmi.*; import java.rmi.server.*; public class ObjServeurRmi extends UnicastRemoteObject implements CalculRmi { private String nomobjserveur; public ObjServeurRmi(String s) throws RemoteException { super(); nomobjserveur = s; public String getnomobjserveur() { return nomobjserveur; Ex. client serveur en Java-RMI // Objet-Serveur RMI (fin) // Fonction main : pour le lancement du serveur static public void main(string arg[]) { System.setSecurityManager(new RMISecurityManager()); try { ServeurRmi srmi = new ObjServeurRmi("Calculateur"); Naming.rebind("//localhost/Calculateur", srmi); System.out.println("Enregistrement objet-serv OK"); catch (Exception e) { System.out.println("Pb enregistrement service: " + e.getmessage()); System.exit(1); 14
Programmation par RPC et Java-RMI : - Principes des RPC - Utilisation d un IDL - Principes des Java-RMI - Mode opératoire des Java-RMI - Hiérarchie de classes Java - Exemple de client-serveur en Java-RMI - RMI entre plusieurs serveurs Mode opératoire des Java-RMI Déploiement simple entre deux machines distantes : Client Stub Server ObjLoc Res = Server.service(ObjLoc) Objets locaux : - passés par valeurs - doivent être serializable Objets distants : - passés par «références» : stubs ObjLoc-copie par valeur Skeleton Server ObjServeur rmiregistry serveur 15
Mode opératoire des Java-RMI Déploiement complexe entre N machines : invocation dynamique de classe Client Stub ObjDist Stub Server ObjLoc Skeleton ObjDist ObjDist Res = Server.service(ObjLoc, «IdObjAndClassDistants») Invoc. Dyna Stub ObjDist Passage d objets locaux : - passés par valeurs ObjLoc-copie par valeur Skeleton Server ObjServeur - doivent être serializable Passage d objets distants : rmiregistry serveur - Nécessitent l invocation dynamique de classes Programmation par RPC et Java-RMI FIN 16