Faire marcher RMI ... avec des ordinateurs distant (par internet)

Dominique49 Messages postés 148 Date d'inscription mardi 10 août 2010 Statut Membre Dernière intervention 19 juin 2016 - 28 juil. 2011 à 09:15
Dominique49 Messages postés 148 Date d'inscription mardi 10 août 2010 Statut Membre Dernière intervention 19 juin 2016 - 12 août 2011 à 10:00
Bonjour à tous,
ça fait des mois que je cherche à faire cela. Jusque là, je n'ai pas trouvé grand monde qui connaisse bien RMI ... j'espère qu'ici il y a des connaisseurs
Bon, venons en au fait
J'ai fait une application de Tchat client Serveur avec RMI.
ça marche en réseaux local ...
Mais ce que je cherche à faire, c'est que ça marche avec un autre ordi distant, connecté à internet, cela va de soi ...

Alors ce que j'ai fait, c'est que, à la récupération du registre de l'ordi serveur, au lieu de saisir le nom du PC, je rentre l'aresse IP. (pas l'adresse IP locale, l'adresse IP internet)
ça marche aussi bien en réseaux local ... mais ça marche pas avec un ordi distant !!
Voilà le bout de code en question :

Côté client :

try {
       LocateRegistry.createRegistry(1099);
       alert("rmiregistry bien lancé !");
} catch (RemoteException e1) {
       System.err.println("rmiregistry est déjà lancé sur ce port");
       alert("Erreur au lancement de rmiregistry.");
}

try {

r = LocateRegistry.getRegistry("192.168.1.14");
alert("connexion avec 192.168.1.14 effective");

} catch (Exception e) {
alert("Erreur lors de la connexion à la machine 192.168.1.14 !");
e.printStackTrace();



Donc dans ce code, j'ai récupéré le registre distant grâce à l'IP : "192.168.1.14". ça marche aussi bien avec "blanc", car c'est le nom de mon PC.
Bon, le pb, c'est que ça ne marche pas ...
enfin, l'erreur ne vient pas de ce bout de code, mais du .lookup()

Bon, après mûre réflexion, je me suis dit que la classe LocatRegitry ne s'appelait pas comme ça pour rien ... et donc que LocateRegistry ne marche qu'en réseaux local ... c'est vrai ?
Dans ce cas, commet communiquer avec un PC distant sur internet ?!
Merci d'avance.

EDIT

Si vous désirez le reste du code, dites le moi, bien que je doute que ce soit très utile ...

37 réponses

coucou747 Messages postés 12303 Date d'inscription mardi 10 février 2004 Statut Membre Dernière intervention 30 juillet 2012 44
28 juil. 2011 à 10:57
Bonjour,

Es-tu sur que le port n'est pas bloqué ?
Il y a plusieurs années, j'ai pu faire du RMI sur le net, et euh... c'est une mauvaise idée : c'est terriblement lent
0
Utilisateur anonyme
28 juil. 2011 à 11:40
Bonjour

Je peux te fournir quelques exemples de programmes utilisant RMI qui marchent et qui paramètrent bien la security policy si tu veux. J'avais fait un jeu de combat en 2D un peu bâclé en réseau avec RMI il y a quelques années...









T.U.E.R (First Person Shooter créé par Julien Gouesse)
0
Utilisateur anonyme
28 juil. 2011 à 11:42
coucou747, RMI n'est pas ce qu'il y a de mieux en terme de vitesse mais c'est suffisant pour un grand nombre d'applications. D'autres solutions existent (Apache Mina, JGN, Kryonet API, etc...) mais elles sont moins faciles à utiliser.












T.U.E.R (First Person Shooter créé par Julien Gouesse)
0
Dominique49 Messages postés 148 Date d'inscription mardi 10 août 2010 Statut Membre Dernière intervention 19 juin 2016
28 juil. 2011 à 12:16
Salut,
je ne crois pas que mon port soit bloqué ...
J'utilise Comodo comme pare-feu (le pare-feu de windows xp c'est un lourdaud qui fait mal son boulot !), et normalement il m’avertirais ...
Le PC distant sur lequel j'ai testé l'appli marche aussi avec COMODO ... donc je ne crois pas que ce soit le pare feu ...

Mais la classe s'appelle LocateRegistry, ce qui veux dire réseaux local ...

Je vais essayer avec des sockets, voir si ça marche mieux ...

Je peux te fournir quelques exemples de programmes utilisant RMI qui marchent et qui paramètrent bien la security policy si tu veux.


Tu pourrais me passer les liens stp ?
Sinon, que me conseillerai vous.
Mon programme est destiné à faire tourner une école en réseaux, et j'ai trouvé RMI drôlement simple ...

Sur ce site, j'ai trouvé plein de source pour des appli de tchat ... elles marchent toutes, mais uniquement en réseaux local ....
La meilleur source que j'ai trouvée est celle-là :

http://www.javafr.com/codes/APPLICATION-CHAT-JAVA-RMI_52174.aspx

Merci beaucoup.

(PS je voudrais être sûr que RMI permet de communiquer avec des ordi distant, c'est possible ?! avec les sockets aussi ?
J'ai lu plein de tutos, mais aucun n'a préciser si les sockets et RMI pouvaient communiquer avec des ordi distants aussi ...

Merci !)
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Utilisateur anonyme
28 juil. 2011 à 13:31
Les sockets sont de plus bas niveau. RMI utilise des sockets mais c'est transparent. Oui RMI permet de faire communiquer des ordinateurs distants sinon je ne vois pas à quoi il servirait.

L'exemple est là :
http://membres.lycos.fr/javalution/projects/fighting.html

Je te conseille de désactiver Comodo dans un premier temps si ça pose problème. VNC ne suffirait-il pas pour faire ce que tu veux?











T.U.E.R (First Person Shooter créé par Julien Gouesse)
0
Dominique49 Messages postés 148 Date d'inscription mardi 10 août 2010 Statut Membre Dernière intervention 19 juin 2016
28 juil. 2011 à 13:44
Je ne connais pas encore VNC ...
Je viens de trouvé ceci :
http://www.javafr.com/code.aspx?ID=20272
ça marche impec en local, je vais l'essayer avec mon amis dès que je pourrai (ce soir). Je verrais bien si ça marche aussi impec.
Si ça marche pas, on désactivera COMODO ... et si ça marche pas ... je pense que je risque d'éclater alors

Merci beaucoup ! (je regarde ton lien)
0
Dominique49 Messages postés 148 Date d'inscription mardi 10 août 2010 Statut Membre Dernière intervention 19 juin 2016
28 juil. 2011 à 14:07
Peut-être es-ce qu'en utilisant le protocole Naming au lieu du protocole LocateRegistry ça marcherai mieux ... J'en ferais l'essaie
0
Utilisateur anonyme
28 juil. 2011 à 16:07
Franchement, tu donnes l'impression de faire du bricolage sans réellement comprendre ce que tu manipules. As-tu jeté un coup à la documentation de l'API standard Java et aux tutoriels officiels d'Oracle? Je te conseille de lire ce tutoriel en entier, ça explique comment utiliser RMI, étape par étape :
http://download.oracle.com/javase/tutorial/rmi/index.html










T.U.E.R (First Person Shooter créé par Julien Gouesse)
0
Dominique49 Messages postés 148 Date d'inscription mardi 10 août 2010 Statut Membre Dernière intervention 19 juin 2016
28 juil. 2011 à 18:11
Salut,
en fait, je bricole pour trouver le moyen ...
je ne demande pas mieux que de faire ça propre, mais pour le moment, je cherche le grain de sable qui bousille les engrenages ...
Merci pour le conseil, j'ai lu plein de tuto (français), mais pas la doc officielle
Bon, merci, je regarde ça.
0
Dominique49 Messages postés 148 Date d'inscription mardi 10 août 2010 Statut Membre Dernière intervention 19 juin 2016
29 juil. 2011 à 09:26
échec sur toute la ligne, même le mini-chat qui marche avec des sockets ne marche pas. De mon côté, j'ai désactivé mon pare-feu, mais l'autre ne savais même pas comment le faire ...
Mais bon, ça marche pas ... je vais lire ce tuto d'Oracle, merci.
0
Dominique49 Messages postés 148 Date d'inscription mardi 10 août 2010 Statut Membre Dernière intervention 19 juin 2016
29 juil. 2011 à 10:01
Bon, j'ai épluché le tuto d'Oracle ...
Je n'y ai pas appris grand chose, si ce n'est quelque petite précision.
Mais sinon, tout est en ordre ... Voilà un extrait du tuto :

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.math.BigDecimal;
import compute.Compute;

public class ComputePi {
    public static void main(String args[]) {
        if (System.getSecurityManager() == null) {
            System.setSecurityManager(new SecurityManager());
        }
        try {
            String name = "Compute";
            Registry registry = LocateRegistry.getRegistry(args[0]);
            Compute comp = (Compute) registry.lookup(name);
            Pi task = new Pi(Integer.parseInt(args[1]));
            BigDecimal pi = comp.executeTask(task);
            System.out.println(pi);
        } catch (Exception e) {
            System.err.println("ComputePi exception:");
            e.printStackTrace();
        }
    }    
}


Le problème, c'est qu'ils ne dise pas ce qu'ils ont passé en args[0] !
Il dise juste que c'est le nom de la machine distante. ça je le savais déjà ... mais ça ne marche pas avec des ordi distant.
Mais, une phrase a retenue mon attention :

voir ici :

Locate remote objects. Applications can use various mechanisms to obtain references to remote objects. For example, an application can register its remote objects with RMI's simple naming facility, the RMI registry. Alternatively, an application can pass and return remote object references as part of other remote invocations.


Autrement dit, le registre RMI est là pour nous faciliter la vie ... mais il y a d'autre alternative pour les appli distante. En bref, j'ai comme dans l'idée que la Classe LocateRegistry ne marche qu'en réseaux local.

En me renseignant encore, j'ai trouvé que l'on pouvait aussi utilisé la classe Naming, je vais donc essayé avec cette dernière ...

a+
0
Dominique49 Messages postés 148 Date d'inscription mardi 10 août 2010 Statut Membre Dernière intervention 19 juin 2016
29 juil. 2011 à 10:02
ah, j'oubliais, pensez vous que System.setSecurityManager(new SecurityManager()); peu jouer ? Je vais essayer avec et sans.
0
Dominique49 Messages postés 148 Date d'inscription mardi 10 août 2010 Statut Membre Dernière intervention 19 juin 2016
29 juil. 2011 à 10:11
Cette fois, je crois avoir trouvé.
Il faut utilise LocateRegistry et Naming !!
Il faut utilisé Naming au Rebind, pour préciser le destinataire.
C'est ce code trouvé sur Wikipédia qui m'a mis sur la piste :

import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.RMISecurityManager;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.registry.*; 
 
public class RmiServer extends UnicastRemoteObject 
    implements RmiServerIntf {
    public static final String MESSAGE = "Hello world";
 
    public RmiServer() throws RemoteException {
    }
 
    public String getMessage() {
        return MESSAGE;
    }
 
 
    public static void main(String args[]) {
        System.out.println("RMI server started");
 
        // Create and install a security manager
        if (System.getSecurityManager() == null) {
            System.setSecurityManager(new RMISecurityManager());
            System.out.println("Security manager installed.");
        } else {
            System.out.println("Security manager already exists.");
        }
 
        try { //special exception handler for registry creation
            LocateRegistry.createRegistry(1099); 
            System.out.println("java RMI registry created.");
        } catch (RemoteException e) {
            //do nothing, error means registry already exists
            System.out.println("java RMI registry already exists.");
        }
 
        try {
            //Instantiate RmiServer
            RmiServer obj = new RmiServer();
 
            // Bind this object instance to the name "RmiServer"
            Naming.rebind("//localhost/RmiServer", obj);
 
            System.out.println("PeerServer bound in registry");
        } catch (Exception e) {
            System.err.println("RMI server exception:" + e);
            e.printStackTrace();
        }
    }
}


Lien
Regardez bien ça :
 Naming.rebind("//localhost/RmiServer", obj);

JE crois que c'est ça ...
Je fais les essais dès que je peux !
0
Utilisateur anonyme
29 juil. 2011 à 10:16
Bonjour

Le security manager est très important, regarde dans mon code, il faut le paramétrer correctement pour que tu puisses utiliser les bons ports avec les bonnes permissions.

Au lieu d'y aller à tâtonner, regarde dans la documentation de l'API Java à chaque fois que tu ne comprends pas à quoi sert un paramètre, une classe, une méthode.

Dans mon code, il est très clair que les arènes sont des objets distants sur le serveur auxquels tu accèdes sur les clients.

Bon courage.








T.U.E.R (First Person Shooter créé par Julien Gouesse)
0
Dominique49 Messages postés 148 Date d'inscription mardi 10 août 2010 Statut Membre Dernière intervention 19 juin 2016
29 juil. 2011 à 10:47
Salut,
je viens de trouvé ... une erreur grosse comme une montagne.
Simplement, je pouvant pas aller voir mon ip sur monip.org à cause d'un contrôle parental, j'ai fait un InnetAdress.getHost ... ce qui ma donné une ip du genre 192.168.1.14 .. qui est en fait une IP locale !
de quoi faire rager ...
Bon, j'ai réussi à trouvé ma véritable IP public.
Mais lorsque que je fais le rebind, ça marche pas ...

L'exception :

java.rmi.ConnectException: Connection refused to host: 90.25.102.103; nested exception is:
java.net.ConnectException: Connection refused: connect
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(Unknown Source)
at sun.rmi.transport.tcp.TCPChannel.createConnection(Unknown Source)
at sun.rmi.transport.tcp.TCPChannel.newConnection(Unknown Source)
at sun.rmi.server.UnicastRef.newCall(Unknown Source)
at sun.rmi.registry.RegistryImpl_Stub.rebind(Unknown Source)
at MessengerImpl2.(MessengerImpl2.java:99)
at MessengerImpl2.main(MessengerImpl2.java:130)
Caused by: java.net.ConnectException: Connection refused: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(Unknown Source)
at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.(Unknown Source)
at java.net.Socket.(Unknown Source)
at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(Unknown Source)
at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(Unknown Source)
... 7 more


pareil avec LocateRegistry ...
0
Dominique49 Messages postés 148 Date d'inscription mardi 10 août 2010 Statut Membre Dernière intervention 19 juin 2016
29 juil. 2011 à 11:04
J'ai essayé un code basique avec socket.
Le client ne peu pas se connecter au socket avec l'IP public.
La méthode .accept qui attend la connexion ne reçoit rien du tout ...
Je ne sait vraiment pas que faire ...
Voici les code :

import java.io.IOException;
import java.net.ServerSocket;


public class Serveur {
public static void main(String[] args){

try {
ServerSocket s = new ServerSocket(3745, 10);
System.out.println("En attente de connexion ...");
s.accept();
System.out.println("Connexion réussie !!!!!");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}



import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;


public class Cient {
public static void main(String[] args){
try {
Socket s= new Socket("90.25.102.103", 3745);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Connecté au serveur !!!");
}
}


cette fois je suis sûr de mon IP ...
remarquez que quand je la remplace par le nom de mon PC, ça marche ...

toujours la même erreur :

java.net.ConnectException: Connection refused: connect
Connecté au serveur !!!
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(Unknown Source)
at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.(Unknown Source)
at java.net.Socket.(Unknown Source)
at Cient.main(Cient.java:9)
0
Dominique49 Messages postés 148 Date d'inscription mardi 10 août 2010 Statut Membre Dernière intervention 19 juin 2016
29 juil. 2011 à 11:08
Excuse-moi, je n'avais pas vu ton message.
D'accord, je vais regarder ça ...
Mais qu'entends-tu par "ton code" ?
Le lien vers le jeux 2D programmé avec RMI ?

Mais quand même, ce dernier essai avec les sockets ne devrait-il pas marcher ?

Merci beaucoup
0
Utilisateur anonyme
29 juil. 2011 à 16:05
Oui c'est ça; dans mon exemple de jeu en 2D, j'utilise un fichier dans lequel je configure les permissions pour éviter d'avoir des problèmes du genre :
java.net.ConnectException: Connection refused: connect

Je pensais que tu regarderais plus en détail mon code, cela t'aurait évité pas mal de tracas. Bon courage.














T.U.E.R (First Person Shooter créé par Julien Gouesse)
0
Dominique49 Messages postés 148 Date d'inscription mardi 10 août 2010 Statut Membre Dernière intervention 19 juin 2016
29 juil. 2011 à 17:04
Le problème, c'est que je ne peu pas aller n'importe où à cause d'un certain contrôle parentale qui m’énerve depuis un certain temps.
Il faut que je fasse la demande, et comme mon admin ne voit les demandes qu'une ou de fois par jour ...
Sans compter que les liens de code-sources, c'est une redirection (ça envoie vers une page de code-sources qui redirige vers la page voulue).
Donc j'ai dû_ attendre jusqu'à cet aprem pour enfin avoir le lien ...
Et je me suis tromper, j'ai pris celui qui était écrit en Pygame (j'aurai du lire un peu plus avant de télécharger !)
Mais j'ai trouvé le bon que je suis en train d'éplucher, merci beaucoup !

NB

n'empêche, es-ce que c'est normal que ça ne marche pas avec des sockets simples comme dans mon dernier essai ?
0
Utilisateur anonyme
29 juil. 2011 à 17:14
Oui c'est normal, il faut autoriser certaines opérations depuis certains domaines et certains ports, c'est ce que définit mon fichier. Une option de la JVM permet de le charger en passant son chemin et ça roule. Après, il faut être cohérent et ne se servir que des ports que tu as correctement configurés.

Pour la source, le lien direct est ici, désolé c'est de ma faute :
http://membres.lycos.fr/javalution/download/fighting.zip








T.U.E.R (First Person Shooter créé par Julien Gouesse)
0
Rejoignez-nous