2009-05-26 10 views
11

Chcę udostępnić niektóre informacje między dwiema klasami (A i B), które działają w różnych programach java. Zamiast pisać cały protokół komunikacyjny, chcę w tym celu użyć wbudowanych klas rmi. Obecnie klasa B jest w stanie uruchomić zdalnie metodę należącą do klasy A. Czy w jakiś sposób można użyć tego samego "połączenia" w klasie A, aby wywołać metodę klasy B? W przeciwnym razie prawdopodobnie trzeba zaimplementować drugą usługę RMI ...Czy można stosować dwukierunkowe RMI między dwiema klasami?

Br

Markus

+0

Alternatywą byłoby RMI [SIMON] (http: // dev. root1.de/projects/show/simon) framework. – schlamar

Odpowiedz

9

Jeśli B implementuje Remote, może być eksportowany i przekazywany jako parametr w wywołaniu RMI do A. W tym scenariuszu nie ma potrzeby rejestrowania B w rejestrze RMI, ponieważ klient jest jawnie przekazywany do niego odwołanie.

+0

Mhhh, myślę, że jeśli zrealizuję to w ten sposób, mogą wystąpić pewne niespójności danych między "skopiowanym" a "prawdziwym" B, lub? – Markus

+1

Nie, nie ma "kopii". Kiedy A wywołuje metodę na B, to naprawdę wywołuje zdalne wywołanie metody przez skrót do "rzeczywistego" B. Jest to identyczne z B wywołującym metodę zdalną na A, z tym wyjątkiem, że zamiast sprawdzać obiekt w rejestrze, A odebrał obiekt zdalny jako parametr w wywołaniu metody. – erickson

+0

Jednakże, jeśli się nie mylę, nie zadziała to, gdy B nie będzie w stanie zaakceptować połączeń przychodzących, np. gdy znajduje się w sieci konsumenckiej z NAT. Czy istnieje sposób na wykonywanie wywołań zwrotnych w ramach istniejącego połączenia? –

-1

Jak klasa B wiedzieć o klasie A bez drugiego serwera RMI chociaż? Myślę, że będziesz potrzebować dwóch serwerów.

1

Minęło trochę czasu odkąd używałem RMI, ale IIRC jeśli klasa B implementuje java.rmi.Remote i przekazuje odwołanie do samej instancji jako parametru do metody w klasie A, wtedy klasa A powinna otrzymać kod i metody wywołany zostanie wywołany na oryginalnej instancji.

Jednakże, jeśli masz dużo takich wywołań RMI wracających z powrotem, prawdopodobnie wystąpią problemy z wydajnością.

-1

Obie maszyny JVM musiałyby wdrożyć usługi RMI. Ale to naprawdę bardzo łatwe spojrzenie na różne klasy w java.rmi.

Czego nie możesz zrobić, to użyć jednego połączenia RMI i wykonać dwukierunkową komunikację.

1

Jeśli zdasz B jako argument do metody w A a następnie użyć tego odniesienie do wywołania metody na B Jestem całkiem pewien, że odwrotna połączenie zostanie ustanowione, i jestem prawie pewna, że ​​RMI Registry jest tworzony dla JVM, gdzie znajduje się B. W pewnym momencie wpadło nam to w kłopoty ze szczególnie surowymi regułami firewalla. Nasz kod wyglądał trochę coś podobnego

Web Server

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

Niektóre RMI callbacks wsparcia usług lub słuchaczy, które pozwala się serwerowi asynchronicznego połączenia klient w dół to samo połączenie. (Niestety nie pamiętam nazwy otwartych bibliotek, które to robią, szybki google nie był zbyt pomocny). Standardowy RMI tego nie obsługuje, zamiast tego należy również wystawić klienta jako usługę RMI.

-1

RMI dwukierunkowe:

SERVER:

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

Sprawdź formatowanie – user35443

4

I wdrożone 2 drożny RMI między cleint i serwera z serwerem wystawiając swój niedopałek za pomocą rejestru

  1. Klient dostaje niedopałek serwer
  2. Następnie klient umieszcza swój kodeks jako Observer na serwerze ddObserver metoda
  3. Serwer powiadamia klientów korzystających ten niedopałek

Kod następujący wola daje lepszy pomysł

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); 
     } 
    } 
} 
Powiązane problemy