JavaRush /Blog Java /Random-FR /RMI : pratique d'utilisation

RMI : pratique d'utilisation

Publié dans le groupe Random-FR
Bonjour! Aujourd'hui, nous allons aborder un sujet plutôt intéressant - RMI . Cela signifie Invocation de Méthode à Distance . RMI : pratique d'utilisation - 1Avec RMI, vous pouvez apprendre à deux programmes à communiquer entre eux, même s'ils se trouvent sur des ordinateurs différents. Cela paraît bien? :) Mais ce n’est pas si difficile à faire ! Dans la conférence d'aujourd'hui, nous comprendrons en quoi consiste l'interaction RMI et comment la configurer. La première chose dont nous avons besoin est un client et un serveur . Vous n’avez pas besoin d’approfondir la terminologie informatique. Dans le cas du RMI, il s’agit simplement de deux programmes. L'un d'eux contiendra un objet et le second appellera les méthodes de cet objet. Appeler des méthodes d'un objet dans un programme qui se trouve dans un autre programme - nous n'avons jamais fait cela auparavant ! Il est temps de l'essayer ! :) Afin de ne pas vous noyer dans la nature, que notre programme soit simple. En général, les serveurs effectuent certains types de calculs demandés par le client. Ce sera pareil pour nous. Nous aurons un simple programme de calcul comme serveur. Elle n'aura qu'une seule méthode - multiply(). Il multipliera les deux nombres qui lui seront envoyés par le programme client et renverra le résultat. Tout d'abord, nous avons besoin d'une interface :
import java.rmi.Remote;
import java.rmi.RemoteException;

public interface Calculator extends Remote {

   int multiply(int x, int y) throws RemoteException;
}
Pourquoi avons-nous besoin d’une interface ? Le fait est que le travail de RMI repose sur la création de proxys, que vous avez étudiés dans l'une des conférences précédentes . Et le travail avec les proxys, comme vous vous en souvenez probablement, s'effectue précisément au niveau des interfaces, et non des classes. Il y a 2 exigences importantes pour notre interface !
  1. Il doit hériter de l'interface du jeton distant.
  2. Toutes ses méthodes doivent lancer une RemoteException (cela ne se fait pas automatiquement dans l'EDI, vous devez l'écrire manuellement !).
Nous devons maintenant créer une classe serveur qui implémentera notre interface Calculator. RMI : pratique d'utilisation - 2Tout ici est également assez simple :
import java.rmi.RemoteException;

public class RemoteCalculationServer implements Calculator {

   @Override
   public int multiply(int x, int y) throws RemoteException {
       return x*y;
   }

}
Il n'y a même pas grand chose à commenter ici :) Nous devons maintenant écrire un programme serveur qui configurera et lancera notre classe de calculatrice de serveur. Il ressemblera à ceci:
import java.rmi.AlreadyBoundException;
import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

public class ServerMain {

   public static final String UNIQUE_BINDING_NAME = "server.calculator";

   public static void main(String[] args) throws RemoteException, AlreadyBoundException, InterruptedException {

       final RemoteCalculationServer server = new RemoteCalculationServer();

       final Registry registry = LocateRegistry.createRegistry(2732);

       Remote stub = UnicastRemoteObject.exportObject(server, 0);
       registry.bind(UNIQUE_BINDING_NAME, stub);

       Thread.sleep(Integer.MAX_VALUE);

   }
}
Voyons cela :) Dans la première ligne, nous créons une sorte de variable de chaîne :
public static final String UNIQUE_BINDING_NAME = "server.calculator";
Cette chaîne est le nom unique de l'objet distant . C'est sous ce nom que le programme client pourra retrouver notre serveur : vous le verrez plus tard. Ensuite, nous créons notre objet calculatrice :
final RemoteCalculationServer server = new RemoteCalculationServer();
Tout est clair ici. Ce qui suit est plus intéressant :
final Registry registry = LocateRegistry.createRegistry(2732);
Cette chose appelée Registre est un registre d'objets supprimés . "Supprimé" non pas dans le sens où nous les avons supprimés de l'ordinateur, mais dans le fait que les objets de ce registre sont accessibles à distance depuis d'autres programmes :) LocateRegistry.createRegistry()Nous avons transmis à la méthode le numéro 2732. C'est le numéro de port. Si vous ne savez pas ce qu'est un port, vous pouvez le lire ici , mais pour l'instant, rappelez-vous simplement qu'il s'agit d'un numéro unique par lequel d'autres programmes peuvent trouver notre registre d'objets (vous le verrez également ci-dessous). Allons-nous en. Voyons ce qui se passe dans la ligne suivante :
Remote stub = UnicastRemoteObject.exportObject(server, 0);
Sur cette ligne, nous créons un stub . Un stub encapsule l’intégralité du processus d’appel à distance en lui-même. On peut dire que c’est l’élément le plus important du RMI. Que fait-elle?
  1. Reçoit toutes les informations sur un appel distant à une méthode.
  2. Si la méthode comporte des paramètres, le stub les désérialise. Faites attention à ce point ! Les paramètres que vous transmettez aux méthodes pour les appels distants doivent être sérialisables (après tout, ils seront transmis sur le réseau). Nous n'avons pas un tel problème - nous transmettons simplement des chiffres. Mais si vous transférez des objets, ne l'oubliez pas !
  3. Après cela, il appelle la méthode souhaitée.
Nous passons UnicastRemoteObject.exportObject()notre objet calculateur de serveur à la méthode. De cette façon nous permettons d'appeler ses méthodes à distance. Il ne nous reste plus qu'une chose à faire :
registry.bind(UNIQUE_BINDING_NAME, stub);
Nous « enregistrons » notre stub dans le registre d'objets distants sous le nom que nous avons proposé au tout début. Maintenant, le client peut le trouver ! Vous avez peut-être remarqué qu'à la fin nous mettons en veille le thread principal du programme :
Thread.sleep(Integer.MAX_VALUE);
Nous avons juste besoin de faire fonctionner le serveur pendant longtemps. Nous exécuterons deux méthodes dans IDEa à la fois main(): d'abord celle du serveur (dans la classe ServerMainque nous avons déjà écrite), puis celle du client (dans la classe que ClientMainnous écrirons ci-dessous). Il est important que le programme serveur ne s'arrête pas pendant le lancement du client, nous le mettons donc simplement en veille pendant une longue période. Cela fonctionnera toujours :) Nous pouvons maintenant exécuter main()notre méthode serveur. Laissez-le s'exécuter et attendez que le programme client appelle une méthode :) Maintenant, écrivons un programme client ! Il enverra des nombres à notre serveur pour les multiplier.
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class ClientMain {

   public static final String UNIQUE_BINDING_NAME = "server.calculator";

   public static void main(String[] args) throws RemoteException, NotBoundException {

       final Registry registry = LocateRegistry.getRegistry(2732);

       Calculator calculator = (Calculator) registry.lookup(UNIQUE_BINDING_NAME);

       int multiplyResult = calculator.multiply(20, 30);

       System.out.println(multiplyResult);
   }
}
Elle a l'air simple. Que se passe t-il ici? Premièrement, le client doit connaître le nom unique de l'objet dont il appellera les méthodes à distance. Par conséquent, dans le programme client, nous avons également créé une variable. public static final String UNIQUE_BINDING_NAME = "server.calculator"; Ensuite, dans la méthode, main()nous avons accès au registre des objets distants. Pour ce faire, nous devons appeler la méthode LocateRegistry.getRegistry()et y transmettre le numéro de port sur lequel notre registre a été créé dans le programme ServerMain - port 2732 (ce numéro a été choisi pour l'exemple, vous pouvez essayer d'en utiliser un autre) :
final Registry registry = LocateRegistry.getRegistry(2732);
Il ne reste plus qu'à récupérer l'objet souhaité dans le registre ! C'est facile car nous connaissons son nom unique !
Calculator calculator = (Calculator) registry.lookup(UNIQUE_BINDING_NAME);
Faites attention au casting de caractères. Nous convertissons l'objet résultant en une interface Calculatorplutôt qu'en une classe concrète RemoteCalculationServer . Comme nous l'avons dit au début du cours, RMI est basé sur l'utilisation d'un proxy, donc un appel à distance n'est disponible que pour les méthodes d'interfaces, pas pour les classes. A la fin, nous appelons à distance une méthode multiply()sur notre objet et imprimons le résultat sur la console.
int multiplyResult = calculator.multiply(20, 30);
System.out.println(multiplyResult);
Nous avons lancé la méthode main()dans la classe ServerMainil y a longtemps, il est temps de lancer la méthode main()dans le programme client ClientMain! Sortie console : 600 C'est tout ! Notre programme (même deux !) a rempli sa fonction avec succès :) Si vous avez le temps et l'envie, vous pouvez le diversifier un peu. Par exemple, assurez-vous que la calculatrice prend en charge les quatre opérations standard, et non les nombres, mais un objet, qui sont transmis en tant que paramètres CalculationInstance(int x, int y). Comme matériel supplémentaire, vous pouvez consulter des articles et des exemples - ici : Rendez-vous aux prochains cours ! :)
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION