2009-05-26 10 views
11

Quiero compartir información entre dos clases (A y B), que se ejecutan en diferentes programas de Java. En lugar de escribir un protocolo de comunicación completo, quiero usar las clases rmi incorporadas en java para ese fin. Actualmente, la clase B puede ejecutar un método que pertenece a la clase A de forma remota. ¿Es de algún modo posible usar la misma "conexión" dentro de la clase A para llamar a un método de clase B? De lo contrario probablemente tenga que aplicar un segundo servicio RMI ...¿Es posible usar RMI bidireccional entre dos clases?

BR,

Markus

+0

Una alternativa a la RMI sería el [SIMON] (http: // dev. root1.de/projects/show/simon) framework. – schlamar

Respuesta

9

Si B implementa Remote, se puede exportar y pasar como parámetro en una llamada RMI al A. En este escenario, no es necesario registrar B en un registro RMI, ya que al cliente se le pasa una referencia explícitamente.

+0

Mhhh, creo que si lo implemento de esa manera podría ocurrir algunas inconsistencias de datos entre la B "copiada" y la "real", o? – Markus

+1

No, no hay "copia". Cuando A llama un método en B, en realidad está invocando una llamada a método remoto a través de un resguardo al "real" B. Es idéntico a B invocando un método remoto en A, excepto que en lugar de buscar el objeto en un registro, A recibió el objeto remoto como un parámetro en una llamada a método. – erickson

+0

Sin embargo, si no me equivoco, esto no funcionará cuando B no pueda aceptar las conexiones entrantes, p. cuando está en una red de consumidores con NAT. ¿Hay alguna manera de hacer devoluciones de llamada sobre la conexión ya existente? –

-1

¿Cómo sería la clase B saber acerca de la clase A sin un segundo servidor RMI sin embargo? Creo que vas a necesitar dos servidores.

1

Ha pasado un tiempo desde que utilicé RMI, pero IIRC si la clase B implementa java.rmi.Remote y pasa una referencia a una instancia de sí mismo como parámetro del método en la clase A, entonces la clase A debería recibir un stub y métodos llamado se llamará a la instancia original.

Sin embargo, si tiene muchas de esas llamadas RMI que van hacia atrás y hacia atrás, es probable que encuentre problemas de rendimiento.

-1

Ambas JVM necesitarían implementar servicios de RMI. Pero eso es realmente muy fácil de ver las diferentes clases en java.rmi.

Lo que no puede hacer es usar de alguna manera una conexión RMI y hacer una comunicación bidireccional.

1

Si pasa B como un argumento a un método en el A y luego utiliza esa referencia para llamar a un método en B Estoy bastante seguro de que se establezca una conexión inversa, y estoy bastante seguro de que se crea RMI registro para el JVM donde reside B. En algún momento esto nos metió en problemas con reglas de firewall especialmente estrictas. Nuestro código se veía un poco algo como

servidor Web

public int uploadFile(FileItem fileItem){ 
    return ApplicationClassLoader 
     .get(DocumentManager.class) 
     .attachFile(new RemoteInputStreamImpl(fileItem.getInputStream()); 
    ) 
} 

Application Server

public int attachFile(RemoteInputStream in){ 
    ... 

    byte[] buffer; 
    while((buffer = in.read(1024)) != null) // Would return null to indicate EOF 
     // Do some stuff 

    return documentId;  
} 
-1

Algunos RMI devoluciones de llamada de soporte de servicio u oyentes que permiten al servidor de llamada asincrónica el cliente abajo la misma conexión (Lo siento, no recuerdo el nombre de las bibliotecas abiertas que hacen esto, un Google rápido no fue muy útil) La RMI estándar no es compatible con esto, en su lugar, debe exponer al cliente como un servicio de RMI también.

-1

RMI bidireccional:

SERVIDOR:

import java.io.IOException; 
import java.rmi.Naming; 
import java.rmi.RemoteException; 
import java.util.logging.Level; 
import java.util.logging.Logger; 

public class RMISERVER { 

    public RMISERVER() throws IOException { 

     Thread t; 
     try { 
      t = new Prou_run(); 
      t.start(); 
     } catch (RemoteException ex) { 
      Logger.getLogger(RMISERVER.class.getName()).log(Level.SEVERE, null, ex); 
     } 

    } 


    public static void main(String args[]) throws IOException { 
    new RMISERVER(); 
    } 
} 


import java.io.File; 
import java.io.IOException; 
import java.net.ServerSocket; 
import java.net.Socket; 
import java.rmi.Naming; 
import java.rmi.Remote; 
import java.rmi.registry.Registry; 
import java.rmi.server.RMIClientSocketFactory; 
import java.rmi.server.RMIServerSocketFactory; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.swing.tree.DefaultMutableTreeNode; 

//extends java.rmi.server.UnicastRemoteObject 
public class Prou_run extends Thread implements Runnable{ 

      New_Object root = null,root2=null,root3=null,root4=null,root5; 
       New_Object new_root=null; 
      Object xt = null, xt2=null , xt3=null; 
      Registry r1,r2; 
      RMIClientSocketFactory csf,csf2; 
      RMIServerSocketFactory ssf,sf2; 


      new_Patryk npal; 

public Prou_run() throws java.rmi.RemoteException, IOException 
{ 
     if (System.getSecurityManager() == null) { 
      System.setSecurityManager(new SecurityManager()); 
        } 

//   csf = new RMIClientSocketFactory() { 
// 
//    public Socket createSocket(String host, int port) throws IOException { 
//     return new Socket("rmi://localhost/getchil",1080); 
//    } 
//   }; 
//   csf2 = new RMIClientSocketFactory() { 
// 
//    public Socket createSocket(String host, int port) throws IOException { 
//     return new Socket("rmi://localhost/getchild",1081); 
//    } 
//   }; 
//   ssf=new RMIServerSocketFactory() { 
// 
//    public ServerSocket createServerSocket(int port) throws IOException { 
//     return new ServerSocket(1099); 
//    } 
//   };// ssf.createServerSocket(1099); 
//    sf2=new RMIServerSocketFactory() { 
// 
//    public ServerSocket createServerSocket(int port) throws IOException { 
//     return new ServerSocket(1098); 
//    } 
//   };//sf2.createServerSocket(1098); 
     try { 
     r1=java.rmi.registry.LocateRegistry.createRegistry(1098); 
       r2=java.rmi.registry.LocateRegistry.createRegistry(1099);//, csf2, ssf); 
       java.rmi.registry.LocateRegistry.createRegistry(1097); 
       java.rmi.registry.LocateRegistry.createRegistry(1095); 
       java.rmi.registry.LocateRegistry.createRegistry(1096); 
     System.out.println("RMI registry ready."); 
     } catch (Exception e) { 
     System.out.println("Exception starting RMI registry:"); 
     e.printStackTrace(); 
     } 
     this.xt = null;this.xt2 = null;this.xt3 = null; 
     npal = new new_Patryk(); 
     System.out.println("sdmmmfxxxxxxxx"); 

    } 






    public void run() { 

//while(true){ 

     try{ 

//    root = new_root; 
//    xt=npal.getChild((File)new_root.getob(), (int)new_root.geti()); 
      New_ObjectIMPL sl = new New_ObjectIMPL(); 
      sl.i=354; 
       System.out.println("sdmmmf2"); 
       //r2 
      Naming.rebind("rmi://localhost:1099/getchild",(New_Object) sl); 
       System.out.println("sdmmmf3"); 

     }catch (Exception e) { 
     System.out.println("Trouble: " + e); 
    } 

     while(new_root==null){ 
      try{ 
       //System.out.println("sdmmmf1" + new_root.geti()); 
     new_root = (New_Object) Naming.lookup("rmi://localhost:1080/getchil"); 
     System.out.println("sdmmmf1" + new_root.geti()); 
      }catch (Exception e) { 
     System.out.println("Trouble: " + e); 
    } 
     } 
    } 

} 

























/** 
* 
* @author austinchuma 
*/ 
public interface New_Object extends java.rmi.Remote { 

    public int geti() throws java.rmi.RemoteException; 

    public Object getob() throws java.rmi.RemoteException; 

    public Object getobchild() throws java.rmi.RemoteException; 

     public boolean getbbol() throws java.rmi.RemoteException; 

     public byte[] getb() throws java.rmi.RemoteException; 



} 





public class New_ObjectIMPL extends java.rmi.server.UnicastRemoteObject implements New_Object 

{ 
    Object ob = null,obchild = null; 
    int i=0; 
    boolean bol = false; 
    byte[] b = null; 

    public New_ObjectIMPL() throws RemoteException{ 
     ob = null;obchild = null; 
     i=0; 
     bol = false; 
     b = null; 
    } 

    public int geti() throws RemoteException { 
     return i; 
      } 

    public Object getob() throws RemoteException { 

     return ob; 
    } 

    public Object getobchild() throws RemoteException { 
     return obchild; 
    } 

    public boolean getbbol() throws RemoteException { 
     return bol; 
    } 

    public byte[] getb() throws RemoteException { 

     return b; 

    } 


} 
+0

Por favor, compruebe el formato – user35443

4

implementé 2 vías RMI entre cleint y el servidor con el servidor de exponer su talón de usar Registro

  1. el cliente obtiene un cabo de el servidor
  2. Luego el cliente coloca su talón como Observer en el servidor a Método ddObserver
  3. El servidor notifica a los clientes que utilizan este trozo

Lo siguiente código da una mejor idea

import java.rmi.*; 
import java.rmi.registry.*; 
import java.rmi.server.*; 
import java.util.Observable; 
import java.util.Observer; 
import java.net.*; 

import javax.rmi.ssl.SslRMIClientSocketFactory; 
import javax.rmi.ssl.SslRMIServerSocketFactory; 

interface ReceiveMessageInterface extends Remote 
{ 
    /** 
    * @param x 
    * @throws RemoteException 
    */ 
    void receiveMessage(String x) throws RemoteException; 

    /** 
    * @param observer 
    * @throws RemoteException 
    */ 
    void addObserver(Remote observer) throws RemoteException; 
} 

/** 
* 
*/ 
class RmiClient extends UnicastRemoteObject 
{ 
    /** 
    * @param args 
    */ 
    static public void main(String args[]) 
    { 
     ReceiveMessageInterface rmiServer; 
     Registry registry; 
     String serverAddress = args[0]; 
     String serverPort = args[1]; 
     String text = args[2]; 
     System.out.println("sending " + text + " to " + serverAddress + ":" + serverPort); 
     try 
     { // Get the server's stub 
      registry = LocateRegistry.getRegistry(serverAddress, (new Integer(serverPort)).intValue()); 
      rmiServer = (ReceiveMessageInterface) (registry.lookup("rmiServer")); 

      // RMI client will give a stub of itself to the server 
      Remote aRemoteObj = (Remote) UnicastRemoteObject.exportObject(new RmiClient(), 0); 
      rmiServer.addObserver(aRemoteObj); 

      // call the remote method 
      rmiServer.receiveMessage(text); 
      // update method will be notified 
     } 
     catch (RemoteException e) 
     { 
      e.printStackTrace(); 
     } 
     catch (NotBoundException e) 
     { 
      System.err.println(e); 
     } 
    } 

    public void update(String a) throws RemoteException 
    { 
     // update should take some serializable object as param NOT Observable 
     // and Object 
     // Server callsbacks here 
    } 
} 

/** 
* 
*/ 
class RmiServer extends Observable implements ReceiveMessageInterface 
{ 
    String address; 
    Registry registry; 

    /** 
    * {@inheritDoc} 
    */ 
    public void receiveMessage(String x) throws RemoteException 
    { 
     System.out.println(x); 
     setChanged(); 
     notifyObservers(x + "invoked me"); 
    } 

    /** 
    * {@inheritDoc} 
    */ 
    public void addObserver(final Remote observer) throws RemoteException 
    { 
     // This is where you plug in client's stub 
     super.addObserver(new Observer() 
     { 
      @Override 
      public void update(Observable o, 
       Object arg) 
      { 
       try 
       { 
        ((RmiClient) observer).update((String) arg); 
       } 
       catch (RemoteException e) 
       { 

       } 
      } 
     }); 
    } 

    /** 
    * @throws RemoteException 
    */ 
    public RmiServer() throws RemoteException 
    { 
     try 
     { 
      address = (InetAddress.getLocalHost()).toString(); 
     } 
     catch (Exception e) 
     { 
      System.out.println("can't get inet address."); 
     } 
     int port = 3232; 
     System.out.println("this address=" + address + ",port=" + port); 
     try 
     { 
      registry = LocateRegistry.createRegistry(port); 
      registry.rebind("rmiServer", this); 
     } 
     catch (RemoteException e) 
     { 
      System.out.println("remote exception" + e); 
     } 
    } 

    /** 
    * 
    * @param args 
    */ 
    static public void main(String args[]) 
    { 
     try 
     { 
      RmiServer server = new RmiServer(); 
     } 
     catch (Exception e) 
     { 
      e.printStackTrace(); 
      System.exit(1); 
     } 
    } 
} 
Cuestiones relacionadas