¿Por qué utilizar RMI?
En este proyecto, pensé en muchas formas de comunicarme entre el cliente y el servidor. Como estaba trabajando en una aplicación de cliente enriquecida, finalmente seleccioné la tecnología entre RMI y Java-sockets. Entre ellos, RMI La flexibilidad no es alta. Tanto el cliente como el servidor deben estar escritos en Java, pero es más conveniente de usar. Por otro lado, java-sockets, aunque es más flexible, necesita definir el protocolo de comunicación entre el servidor y el cliente. Es bastante problemático. Después de sopesarlo varias veces, finalmente elegí RMI para la comunicación servidor-cliente.
problema de carga de archivos
En el proceso de uso de java-rmi, inevitablemente encontrará un problema de carga de archivos. Dado que los flujos de archivos no se pueden transmitir en rmi (por ejemplo, los parámetros del método en rmi no pueden ser FileInputStream y similares), entonces tenemos que elegir un compromiso. La mejor manera es usar primero FileInputStream para leer el archivo en una matriz de bytes, luego pasar esta matriz de bytes como parámetro al método RMI y luego restaurar la matriz de bytes a un flujo de salida en el lado del servidor, para que pueda ser. pasó por RMI Transfiramos archivos
Esto también tiene la desventaja de que no se puede verificar la exactitud de los datos transmitidos.
Déjame explicarlo con un ejemplo a continuación.
Cliente de archivos
Copie el código de código de la siguiente manera:
carga del paquete rmiupload;
importar java.io.BufferedInputStream;
importar java.io.File;
importar java.io.FileInputStream;
importar java.io.FileNotFoundException;
importar java.io.IOException;
importar java.net.MalformedURLException;
importar java.rmi.Naming;
importar java.rmi.NotBoundException;
importar java.rmi.RemoteException;
clase pública FileClient {
Cliente de archivo público() {
// TODO Código auxiliar de constructor generado automáticamente
}
público estático vacío principal (String [] argumentos) {
intentar {
FileDataService fileDataService = (FileDataService) Naming.lookup("rmi://localhost:9001/FileDataService");
fileDataService.upload("/Users/NeverDie/Documents/test.mp4", new FileClient().fileToByte("/Users/NeverDie/Music/test.mp4"));
} captura (MalformedURLException | RemoteException | NotBoundException e) {
// TODO Bloque de captura generado automáticamente
e.printStackTrace();
}
}
// Este método es más importante. A través de este método, un archivo llamado nombre de archivo se convierte en una matriz de bytes.
byte privado[] fileToByte(nombre de archivo de cadena){
byte[] b = nulo;
intentar {
Archivo archivo = nuevo Archivo (nombre de archivo);
b = nuevo byte[(int) file.length()];
BufferedInputStream es = new BufferedInputStream(new FileInputStream(archivo));
es.read(b);
} captura (FileNotFoundException e) {
// TODO Bloque de captura generado automáticamente
e.printStackTrace();
} captura (IOException e) {
// TODO Bloque de captura generado automáticamente
e.printStackTrace();
}
volver b;
}
}
Servicio de datos de archivo
carga del paquete rmiupload;
importar java.net.URL;
importar java.rmi.Remote;
importar java.rmi.RemoteException;
La interfaz pública FileDataService extiende Remote{
//El nombre del archivo aquí debe ser la dirección donde se almacena el archivo en el lado del servidor
la carga pública vacía (nombre de archivo de cadena, archivo de bytes []) genera RemoteException;
}
FileDataService_imp
Copie el código de código de la siguiente manera:
carga del paquete rmiupload;
importar java.io.BufferedOutputStream;
importar java.io.File;
importar java.io.FileNotFoundException;
importar java.io.FileOutputStream;
importar java.io.IOException;
importar java.net.URL;
importar java.rmi.RemoteException;
importar java.rmi.server.RMIClientSocketFactory;
importar java.rmi.server.RMIServerSocketFactory;
importar java.rmi.server.UnicastRemoteObject;
la clase pública FileDataService_imp extiende UnicastRemoteObject implementa FileDataService{
public FileDataService_imp() lanza RemoteException {
}
@Anular
La carga pública vacía (nombre de archivo de cadena, byte [] contenido de archivo) arroja una excepción remota {
Archivo archivo = nuevo Archivo (nombre de archivo);
intentar {
si (!archivo.existe())
archivo.createNewFile();
BufferedOutputStream os = nuevo BufferedOutputStream (nuevo FileOutputStream (archivo));
os.write(archivoContenido);
} captura (FileNotFoundException e) {
// TODO Bloque de captura generado automáticamente
e.printStackTrace();
} captura (IOException e) {
// TODO Bloque de captura generado automáticamente
e.printStackTrace();
}
; }
}
Servidor de archivos
Copie el código de código de la siguiente manera:
carga del paquete rmiupload;
importar java.net.MalformedURLException;
importar java.rmi.Naming;
importar java.rmi.RemoteException;
importar java.rmi.registry.LocateRegistry;
servidor de archivos de clase pública {
FileDataService fileDataService;
servidor de archivos público() {
intentar {
fileDataService = nuevo FileDataService_imp();
LocalizarRegistry.createRegistry(9001);
Naming.rebind("rmi://localhost:9001/FileDataService", fileDataService);
} captura (RemoteException e) {
// TODO Bloque de captura generado automáticamente
e.printStackTrace();
} captura (MalformedURLException e) {
// TODO Bloque de captura generado automáticamente
e.printStackTrace();
}
}
/**
* argumentos @param
*/
público estático vacío principal (String [] argumentos) {
nuevo servidor de archivos();
}
}