Contamos con tu ayuda para extender nuestras crónicas sobre las ciencias informáticas.
Solución:
RMI generalmente no funcionará sobre un firewall, ya que usa puertos impredecibles (comienza en 1099 y luego se ejecuta con un puerto aleatorio después de eso).
En estas situaciones, generalmente debe recurrir a la tunelización de RMI a través de HTTP, que se describe bien aquí.
Todas las respuestas hasta ahora son incorrectas. El Registro normalmente usa el puerto 1099, pero puede cambiarlo. Pero ese no es el final de la historia. Los objetos remotos también usan puertos, y no necesariamente 1099.
Si no especifica un puerto al exportar, RMI usa un puerto aleatorio. La solución es por tanto para especificar un número de puerto al exportar. Y este es un puerto que necesita abrirse en el firewall, si lo hay.
-
En el caso de que su objeto remoto se extienda
UnicastRemoteObject
, hacer que su constructor llamesuper(port)
con algún número de puerto distinto de cero. -
En el caso de que no se extienda
UnicastRemoteObject
, proporcione un número de puerto distinto de cero paraUnicastRemoteObject.exportObject()
.
Hay varias arrugas en esto.
-
Si no utiliza fábricas de sockets y proporciona un número de puerto distinto de cero al exportar su primer objeto remoto, RMI compartirá automáticamente ese puerto con los objetos remotos exportados posteriormente sin números de puerto especificados o especificando cero. Ese primer objeto remoto incluye un Registro creado conLocateRegistry.createRegistry().
Así que si creas unRegistry
en el puerto 1099, todos los demás objetos exportados desde esa JVM pueden compartir el puerto 1099. -
Si tu son usando fábricas de enchufes, su
RMIServerSocketFactory
debe tener una implementación sensata deequals()
para que funcione el uso compartido de puertos, es decir, uno que no solo dependa de la identidad del objeto a través de==
oObject.equals()
. -
Si cualquiera no proporciona una fábrica de sockets de servidor, o le proporcionas a uno una sensata
equals()
método, pero no ambos, puede usar el mismo número de puerto explícito distinto de cero para todos los objetos remotos, por ejemplocreateRegistry(1099)
seguido de cualquier número desuper(1099)
oexportObject(..., 1099)
llamadas
En RMI, con respecto a los puertos, hay dos mecanismos distintos involucrados:
-
De forma predeterminada, el Registro RMI utiliza el puerto 1099
-
El cliente y el servidor (stubs, objetos remotos) se comunican a través de puertos aleatorios a menos que se haya especificado un puerto fijo al exportar un objeto remoto. La comunicación se inicia a través de una fábrica de sockets que usa 0 como puerto de inicio, lo que significa usar cualquier puerto que esté disponible entre 1 y 65535.