java - software - ¿Cómo tengo que configurar un entorno RMI para que pueda usarlo en una red "real"?
software libre online (2)
Usar diferentes versiones del JDK en cada servidor podría causar este problema.
Use el comando java -version para asegurarse de que está utilizando la misma versión de jre.
Como no quería implementar un protocolo de comunicación para mi aplicación cliente-servidor, implementé un cliente RMI y un servidor RMI en ambos lados para el intercambio de información entre los dos componentes.
Si trato de usar mi aplicación iniciando los dos componentes en la misma máquina, todo funciona bien. Pero si divido los componentes en dos computadoras diferentes (Kubuntu 9.04 dentro como una máquina virtual dentro de un entorno de Windows 7 RC con firewall desactivado y un entorno nativo Ubuntu 9.04), parece que el cliente RMI no puede ejecutar los métodos que son definido en el lado del servidor. (Cada llamada a funciones conduce a una excepción de RMI).
Actualmente, solo configuro la propiedad del sistema "java.rmi.server.hostname" en ambos lados de la interfaz de red que se debe usar para el intercambio de datos y registré el puerto predeterminado para la comunicación con rmi daemon (?) Rmid.
¿Alguien tiene una idea de lo que podría estar yendo mal? ¿Tengo que establecer algunos otros parámetros como "java.rmi.server.codebase" ( http://java.sun.com/j2se/1.4.2/docs/guide/rmi/javarmiproperties.html ) para poder usar la funcionalidad RMI dentro de mi aplicación?
Editar: Bien, aquí hay información adicional para usted:
En la fase de inicialización, mi cliente intenta establecer una conexión con el servidor RMI del componente del servidor, que se inicializó utilizando los dos métodos siguientes:
private void initialize()
{
// set ip address of rmi server
System.setProperty("java.rmi.server.hostname", ipAddress);
// try to register rmi server
try
{
LocateRegistry.createRegistry(Registry.REGISTRY_PORT);
}
catch (Exception e)
{
// ignore
}
}
public void start()
{
System.out.print("starting master control RMI server ...");
try
{
Naming.rebind("MasterControl", this);
}
catch (Exception e)
{
System.out.println("error: could not initialize master control RMI server");
System.exit(1);
}
// set running flag
isRunning = true;
System.out.println(" done");
}
"ipAddress" es aquí la dirección IP de la interfaz de red del componente del servidor.
El método utilizado por el componente del cliente para establecer la conexión se ve así:
public void connect()
{
// build connection url
String url = "rmi://" + masterControlIpAddress + "/MasterControl";
System.out.println(url);
System.out.print("connecting to master control ...");
// try to connect to master control server
while (connection == null)
{
try
{
connection = (MasterControlInterface) Naming.lookup(url);
id = connection.register(localIpAddress);
}
catch (Exception e)
{
// ignore
}
if (connection == null)
{
try
{
Thread.sleep(100);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
System.out.println(" done");
}
Como puede ver, mi cliente llama a una función para registrar la conexión en el servidor:
@Override
public int register(String ipAddress) throws RemoteException
{
// add connection to registrationHandler
masterControl.registrationHandler.addConnection(ipAddress);
// log
int connectionCount = masterControl.registrationHandler.getConnectionCount();
System.out.println("slave control (" + ipAddress + ") instance has been registered at the master control server under the following id: " + connectionCount);
return connectionCount;
}
Si ejecuto mi programa usando una conexión de red real, el texto "control esclavo ..." no se muestra en el lado del servidor. Por lo tanto, no estoy seguro si el componente cliente realmente llama a la función.
Una vez inicializado el componente cliente, intenta notificar al componente del servidor llamando al siguiente método utilizando su conexión RMI al servidor:
public void sendInitializationDone()
{
try
{
connection.initializationDone();
}
catch (RemoteException e)
{
System.out.println("error: could not send ''initializationDone'' message to master control");
System.out.println(e);
System.exit(1);
}
}
para establecer una bandera en el lado del servidor.
El error se produce dentro de esta función en el lado del cliente:
java.rmi.ConnectException: Connection rechazó el host 127.0.1.1; la excepción anidada es: java.net.ConnectException: conexión rechazada.
No tengo idea de por qué el host está aquí 127.0.1.1 ...
@nos
Por supuesto, desactivé el firewall de Windows y el mecanismo de protección de Kaspersky Internet Security. No creo que haya un firewall funcionando en mi Kubuntu. En generell es posible establecer una conexión, porque ya usé scp para copiar mi programa a la otra máquina.
Edit2:
Mhhh, después de configurar la entrada en / etc / hosts que hace referencia a la máquina a la dirección IP de la máquina parece funcionar, pero realmente no entiendo por qué lo hace ...
BR,
Markus
Necesita agregar una entrada al hosts file
de las máquinas que contienen una entrada del formulario
machinename privateip
p.ej
virtualmachine 192.168.1.16
Esto evitará que RMI envíe el nombre de host del host local como una dirección de ''llámame''.
Para probar este enfoque, ejecute el siguiente código antes y después de realizar el cambio.
System.out.println(java.net.InetAddress.getLocalHost());
Debería mostrar una dirección local antes de los cambios y una dirección no local después de los cambios.