Sería más fácil si todos los componentes se ejecutaran en el mismo espacio de almacenamiento dinámico de la misma máquina virtual Java en la misma computadora, pero en la práctica a menudo no nos enfrentamos a una situación tan única. Si el cliente es solo un dispositivo que puede ejecutar Java. ¿hacer? ¿Qué pasa si por razones de seguridad sólo los programas del servidor pueden acceder a la base de datos?
Sabemos que en la mayoría de los casos, las llamadas a métodos ocurren entre dos objetos en el mismo montón. ¿Qué sucede si desea llamar a métodos en objetos en diferentes máquinas?
Por lo general, obtenemos información de una computadora a otra a través del flujo de entrada / salida del socket, abrimos la conexión del socket de la otra computadora y luego obtenemos el flujo de salida para escribir los datos. Pero si queremos llamar a otra computadora en su. Computadora, ¿cuáles son los métodos de los objetos en otra máquina virtual Java? Por supuesto, podemos definir y diseñar nosotros mismos el protocolo de comunicación para llamar y luego transmitir los resultados de la ejecución a través de Socket, y también puede ser como llamar a métodos en la máquina local, es decir, si queremos llamar a objetos remotos (como como otros montones)), pero debería ser como una llamada normal.
Esto es lo que nos trae RMI.
El diseño de llamadas a procedimientos remotos.
Hay 4 cosas para crear: servidor, cliente, instalaciones auxiliares del servidor e instalaciones auxiliares del cliente.
1. Cree aplicaciones de cliente y servidor. La aplicación del servidor es un servicio remoto, un objeto con métodos que el cliente llamará.
2. Cree ayudantes del lado del cliente y del servidor. Manejarán todos los detalles de entrada/salida de la red subyacente del cliente y el servidor, haciendo que el cliente y el programa parezcan estar procesando llamadas locales.
Tareas de las instalaciones auxiliares Las instalaciones auxiliares son objetos que realmente realizan la comunicación. Hacen que el cliente sienta como si estuviera llamando a un objeto local. El objeto del cliente parece estar llamando a un método remoto, pero en realidad solo está llamando a un método. proxy que maneja los detalles del socket y la transmisión localmente. En el lado del servidor, las instalaciones auxiliares del servidor se conectarán a través del socket. La solicitud de la instalación del cliente analiza la información empaquetada y luego llama al servicio real, por lo que la llamada es local para el objeto de servicio. Después de que la instalación auxiliar del servicio obtiene el valor de retorno, lo envuelve y lo envía de vuelta (a través del flujo de salida del socket). ) al ayudante del cliente. El ayudante del cliente descomprimirá la información y la transferirá al objeto del cliente.
El proceso de llamar a un método.
1. El objeto cliente llama a doBigThing() en el objeto de instalación auxiliar.
2. Las instalaciones auxiliares del cliente empaquetan la información de la llamada y la envían a las instalaciones auxiliares del servidor a través de la red.
3. La función auxiliar del lado del servidor decodifica la información de la función auxiliar del lado del cliente y la utiliza para llamar al servicio real.
El diagrama que describe este proceso es el siguiente:
JavaRMI proporciona objetos auxiliares del lado del cliente y del servidor
En Java, RMI nos ha ayudado a crear instalaciones auxiliares del lado del cliente y del servidor. También sabe cómo hacer que las instalaciones auxiliares del lado del cliente parezcan servicios reales. En otras palabras, RMI sabe cómo proporcionar los mismos métodos para las llamadas de los clientes. .
Además, RMI proporciona toda la infraestructura necesaria para la ejecución, incluida la consulta de servicios y las instalaciones auxiliares que permiten a los clientes encontrar y obtener clientes (agentes de servicios reales).
Cuando se utiliza RMI, no es necesario escribir ningún programa de red o de entrada/salida. La llamada del cliente a un método remoto es la misma que la llamada a un método en la misma máquina virtual Java.
Las llamadas generales son un poco diferentes de las llamadas RMI. Aunque para el cliente esta llamada a método parece local, la instalación auxiliar del cliente realizará la llamada a través de la red. Esta llamada eventualmente involucrará sockets y transmisiones. y el agente lo convertirá a uno remoto. La forma en que se envía la información intermedia desde la máquina virtual Java a la máquina virtual Java depende del protocolo utilizado por el objeto de instalación auxiliar.
Al utilizar RMI, debes decidir el protocolo: JRMP o IIOP es el protocolo nativo de RMI. Está diseñado para llamadas remotas entre Java. Por otro lado, IIOP está producido para CORBA, que nos permite llamar a Java. Para objetos u otros tipos de métodos remotos, CORBA suele ser más problemático que RMI, porque si ambos extremos no son Java, se producirán un montón de operaciones terribles de traducción y conversación.
Sólo nos preocupamos por las operaciones de Java a Java, por lo que usaremos un RMI bastante simple.
En RMI, las instalaciones auxiliares del lado del cliente se denominan stubs y las instalaciones auxiliares del lado del servidor se denominan esqueletos.
Cómo crear un servicio remoto
1.Crear interfaz remota
La interfaz remota define los métodos que el cliente puede llamar de forma remota. Es una clase polimórfica como servicio. Tanto el código auxiliar como el servicio implementarán esta interfaz.
2. Implementar la interfaz remota
Esta es la clase de ejecución real. Implementa los métodos definidos en la interfaz. Es el objeto que llamará el cliente.
3. Utilice rmic para generar trozos y esqueletos.
Tanto el cliente como el servidor tienen ayudas. No necesitamos crear estas clases ni generar el código fuente de estas clases. Esto se manejará automáticamente al ejecutar la herramienta rmic adjunta al JDK.
4. Inicie RMIregistry (rmiregistry)
rmiregistry es como una guía telefónica, el usuario obtendrá el proxy (el objeto auxiliar/stub del cliente) desde aquí
5. Inicie el servicio remoto
El objeto de servicio debe comenzar a ejecutarse. La clase que implementa el servicio iniciará la instancia de servicio y la registrará en RMIRegistry. Solo después del registro podrá servir al usuario.
código de servidor
Definir interfaz
/**
*
*MiRemoto.java
*
* Función: TODO
* Nombre de clase: MyRemote.java
*
* ver. Titular de personaje actualizado y nuevo contenido.
*──────────────────────────────────────── ────
* V1.00 2013-3-19 Primera versión del módulo Su Ruo
*
* Copyright (c) 2013 Dennisit Corporation Todos los derechos reservados.
*
* Correo electrónico:<a href="mailto:[email protected]">Enviar correo electrónico</a>
*
*
* Remote es una interfaz marcada, lo que significa que no hay métodos. Sin embargo, tiene un significado especial para RMI, por lo que se debe seguir esta regla.
* Tenga en cuenta que aquí se utiliza extensión y que las interfaces pueden heredar otras interfaces.
*
*/
interfaz pública MyRemote extiende Remote{
/**
* La interfaz remota define los métodos que el cliente puede llamar de forma remota. Es una clase polimórfica como servicio.
* Movilizar el stub que implementa esta interfaz y, dado que este stub realizará el trabajo de red y de entrada/salida, pueden suceder varias cosas.
* Problema, el cliente maneja o declara excepciones para reconocer este tipo de riesgo. Si el método declara una excepción en la interfaz, llame al método.
*Todos los procedimientos deben manejar o redeclarar esta excepción.
*
* Los parámetros y valores de retorno de los métodos remotos deben ser primitivos o serializables. Cualquier parámetro de los métodos remotos lo será.
* El paquete se transmite a través de la red y, cuando se completa mediante serialización, el valor de retorno es el mismo, por lo tanto, si se utiliza un tipo personalizado.
*, debe estar serializado
* @devolver
* @throws RemoteException
* Todos los métodos en la interfaz deben declarar RemoteException
*/
public String sayHello() lanza RemoteException;
}
/**
*
*MiRemoteImpl.java
*
* Función: TODO
* Nombre de clase: MyRemoteImpl.java
*
* ver. Titular de personaje actualizado y nuevo contenido.
*──────────────────────────────────────── ────
* V1.00 2013-3-19 Primera versión del módulo Su Ruo
*
* Copyright (c) 2013 Dennisit Corporation Todos los derechos reservados.
*
* Correo electrónico:<a href="mailto:[email protected]">Enviar correo electrónico</a>
*
* Para convertirse en un objeto de servicio remoto, el objeto debe tener funciones relacionadas con el control remoto. El método más simple es heredar UnicastRemoteObject.
* (de java.rmi.server) para permitir que esta clase principal maneje el trabajo
*
*/
la clase pública MyRemoteImpl extiende UnicastRemoteObject implementa MyRemote{
/**
* El constructor de la clase padre declara una excepción, por lo que debes escribir el constructor porque significa que tu constructor llamará a código de programa riesgoso.
*
* UnicastRemoteObject tiene un pequeño problema, su constructor lanza RemoteException. La única forma de manejarlo es.
* Declare un constructor para su propia implementación para que haya un lugar para declarar RemoteException Cuando se inicializa la clase, la clase principal.
* Definitivamente se llamará al constructor. Si el constructor de la clase principal arroja una excepción, el constructor personalizado que debemos declarar también arrojará una excepción.
* @throws RemoteException
*/
MyRemoteImpl protegido () lanza RemoteException {
}
/**
* Implemente todos los métodos de la interfaz saliente, pero no es necesario declarar RemoteException
*/
@Anular
Cadena pública decir Hola(){
return "el servidor dice, rmi ¡hola mundo!";
}
público estático vacío principal (String [] argumentos) {
intentar {
/**
* Ya tenemos un servicio remoto y debemos permitir que los usuarios remotos accedan a él. Esto se puede hacer inicializándolo y agregándolo al Registro RMI.
* (Debe estar ejecutándose; de lo contrario, este programa fallará). Al registrar un objeto, el sistema RMI agregará el código auxiliar al registro.
* Porque esto es lo que el cliente necesita. Utilice rebind() de java.rmi.Naming para registrar el servicio.
*/
Servicio MyRemote = nuevo MyRemoteImpl();
/**
* Cree un objeto remoto y luego use static Naming.rebind() para crear una asociación. El nombre registrado se proporcionará para la consulta del cliente.
*/
Naming.rebind ("Hola mundo remoto", servicio);
} captura (Excepción e) {
e.printStackTrace();
}
}
}
ejecutivo público vacío(){
intentar {
/**
* El cliente debe obtener el objeto stub porque debe llamar a su método. Esto depende del registro RMI. El cliente consultará el teléfono como.
* Busque en el mismo directorio para encontrar servicios con nombres coincidentes.
* El cliente consulta RMIRegistry y devuelve el objeto stub
* Naming.lookup("rmi://127.0.0.1/Remote Hola mundo");
* Descripción del parámetro
* rmi://127.0.0.1/Remoto Hola mundo
* 127.0.0.1 representa el nombre del host o la dirección IP del host
* Remote Hello World debe ser el mismo que el nombre registrado
*
*/
Servicio MyRemote = (MyRemote)Naming.lookup("rmi://127.0.0.1/Remote Hello World");
Cadena tmp = servicio.sayHello();
System.out.println(tmp);
} captura (Excepción e) {
e.printStackTrace();
}
}
público estático vacío principal (String [] argumentos) {
nuevo MyRemoteClient().exec();
}
}
La herramienta rmic que viene con el JDK generará dos clases, stub y esqueleto, según la implementación del servicio. Agregará _Stub o _Skeleton después del nombre de la implementación remota de acuerdo con las reglas de nomenclatura. rmic tiene varias opciones, incluyendo no generar esqueletos, observar el código fuente de las clases generadas o usar IIOP como protocolo de comunicación. Las clases generadas se colocarán en el directorio actual. Por lo tanto, es posible que deba ejecutar rmic desde el directorio donde se encuentra la implementación (en la práctica, es posible que deba considerar la estructura del directorio del paquete y el nombre completo; por simplicidad, el paquete no se usa aquí)
Llame a la línea de comando para iniciar rmiregistry. Asegúrese de iniciarlo desde un directorio que pueda acceder a la clase. La forma más sencilla es ejecutarlo desde el directorio de la clase.
La captura de pantalla en ejecución es la siguiente.
Aviso:
El cliente usa la interfaz para llamar al método en el código auxiliar. La máquina virtual Java del cliente debe tener una clase de código auxiliar, pero el cliente no hará referencia a la clase de código auxiliar en el código del programa. El cliente siempre opera el objeto remoto real a través de la interfaz.
El servidor debe tener stubs y esqueletos, así como interfaces remotas y de servicio. Requiere la clase stub porque el stub será reemplazado por el servicio real conectado a RMIRegistry.
Errores comunes al usar RMI:
1. Olvidé iniciar rmiregistry antes de iniciar el servicio remoto (se debe iniciar rmiregistry antes de usar Naming.rebind() para registrar el servicio)
2. Olvidé hacer que los parámetros y los tipos de retorno sean serializables (no se detectará durante la compilación y solo se descubrirá durante la ejecución)
3. Olvídese de entregar la clase stub al cliente.
RMI es muy adecuado para escribir y ejecutar servicios remotos, pero no utilizaremos RMI solo para ejecutar servicios de sitios web. Para aplicaciones de nivel empresarial a gran escala, necesitamos más y mejores funciones, como gestión de transacciones y procesamiento concurrente a gran escala. y seguridad y gestión de bases de datos, etc. Esto requiere el uso de EnterpriseApplicationServer.
El servidor JavaEE incluye un servidor web y un servidor Enterprise JavaBeans (EJB). El servidor EJB actúa entre las llamadas RMI y la capa de servicio.
Aplicación de RMI en JINI
Jini también usa RMI (aunque también se pueden usar otros protocolos), pero tiene varias funciones clave más.
1. Descubrimiento adaptativo
2. Redes de autocuración
El cliente RMI primero debe obtener la dirección y el nombre del servicio remoto. El código del programa de consulta del cliente debe contener la dirección IP o el nombre de host del servicio remoto (porque RMIRegistry está en él) y el nombre registrado por el servicio.
Pero al usar JINI, los usuarios solo necesitan saber una cosa: ¡la interfaz implementada por el servicio!
Jini utiliza el servicio de búsqueda, que es más potente y adaptable que RMIRegistry. Porque Jini anunciará automáticamente en la red cuando el servicio de consulta esté en línea y utilizará tecnología de multidifusión IP para enviar información a toda la red. se conecta después de que se ha transmitido el servicio de consulta y el cliente también puede enviar mensajes a toda la red para realizar consultas.
Cuando el servicio esté en línea, explorará dinámicamente el servicio de consulta JINI en la red y solicitará el registro. Al registrarse, el servicio enviará un objeto serializado al servicio de consulta. Este objeto puede ser el código auxiliar del servicio remoto RMI. controlador del dispositivo de red, o incluso el servicio en sí que se puede ejecutar en el cliente. Y lo que se registra es la interfaz implementada, no el nombre.
Cómo funciona la exploración adaptativa
1.El servicio de consulta Jini se inicia en la red y utiliza tecnología de multidifusión IP para promocionarse.
2. Otro servicio Jini que se haya iniciado buscará registrarse con el servicio de consulta recién iniciado. Registra la función en lugar del nombre, es decir, la interfaz implementada, y luego envía el objeto serializado al servicio de consulta.
3. Los clientes de Internet quieren conseguir algo para implementar ScientificCalculator, pero no saben dónde encontrarlo, por lo que solicitan el servicio de consultas.
4. El servicio de consulta responde a los resultados de la consulta.
Funcionamiento de una red de autorreparación
1. Un determinado servicio Jini requiere registro y el servicio de consulta otorgará un contrato de arrendamiento. Los servicios recién registrados deben renovar el contrato de arrendamiento periódicamente. De lo contrario, el servicio de consulta asumirá que el servicio de consulta está fuera de línea. estado completo de la red de servicio disponible.
2. El servicio está fuera de línea debido a un cierre, por lo que el contrato de arrendamiento no se actualiza y se inicia el servicio de consulta.