Question

I ai deux applications communiquant via RMI, un serveur esclave (dont il sera multiple) et d'un serveur maître.

Après une bonne conception abstraite, je voudrais mettre en œuvre l'esclave d'une manière qu'il ne sait pas que quand on parle au maître, il utilise RMI (de sorte que les deux applications peuvent également être exécutées dans la même machine virtuelle Java, par exemple):

public static void main(String[] a) {
     Master ms = magicGetTheMasterFromRMI();
     new Slave(ms);
}

...

class Slave {

   public Slave(Master m) {
       m.registerSlave(this); // PROBLEM LINE   
   }

}

Problème: La ligne PROBLEM LINE marquée ci-dessus ne fonctionne pas, parce que je ne peux pas simplement passer ce (le Slave lui-même est un Remote qui Master va parler de nouveau à). Je dois faire explicitement une UnicastRemoteObject.exportObject(this, 0) (ou toStub(this) si elle est exporté plus tôt), mais qui fait la classe Slave dépendent de RMI, brisant la conception.

En outre, les forces de registerSlave me pour attraper RemoteException, qui ajoute également la dépendance RMI.

Que proposeriez-vous pour résoudre ces problèmes?

(il m'a aussi des bugs que ces classes doivent mettre en œuvre à distance, mais je suppose que nous ne pouvons aller jusqu'à l'abstraction)

Était-ce utile?

La solution

Eh bien, je l'ai fait comme ceci:

interface Service {
   void doIt();
}

class ServiceImpl implements Service {
  public void doIt() { ... }
}

interface RemoteService extends Remote {
  void proxyDoIt() throws RemoteException;
}

class RemoteServiceHost implements RemoteService {
  public void proxyDoIt() throws RemoteException {
    // serviceImpl is a field, defined in the constructor
    serviceImpl.doIt();
  }
}

class RemoteServiceClient implements Service {
  public void doIt() {
   try {
    // remoteService is a field, defined in the constructor
    remoteService.proxyDoIt();
   } catch (RemoteException e) {
    throw new RuntimeException(e);
   }
  }
}

Autres conseils

  

RMI besoins d'exportation explicite   objets

Seulement si elles ne s'étendent pas UnicastRemoteObject ou activable. S'ils le font, ils sont exportés automatiquement sur la construction.

  

Je dois faire explicitement   UnicastRemoteObject.exportObject (cela,   0)

Non, voir ci-dessus.

  

(ou toStub (cela) si elle est exportée   plus tôt)

Quelle que soit toStub () est. Il y a un RemoteObject.toStub (), mais vous ne pouvez pas être appeler comme ça, et si vous vous perdez votre temps.

Mais vous ne devez pas faire cela. Si « ceci » est un objet distant exporté vous pouvez juste passer autour comme un paramètre RMI ou le résultat. RMI remplacera le stub automatiquement.

Je serais méfiant de cette abstraction - les demandes à distance desservies sont différentes des demandes servies sur place à bien des égards -. Latence, modes de défaillance, la sémantique de nouvelle tentative

Il se pourrait que votre abstraction est qui fuit parce que son pas vraiment valide.

Une partie de votre application esclave va être prêt à recevoir l'appel via RMI et traiter RemoteException, etc. Pourquoi ne pas introduire une procuration de quelque sorte entre le maître et l'esclave qui médiatise la communication et cache le RMI vs problème local. Par exemple, le long des lignes de:

public Slave(Master m)
{
   new MasterConnection(m, this);
}

class MasterConnection implements Slave extends UnicastRemoteObject
{
   Slave s;

   public MasterConnection(Master m, Slave s) throws IOException
   {
      this.slave = s;
      try {
         exportObject(this);
      } catch (RemoteException e){
         throw new IOException("Could not communicate with Master etc....");
      }
      master.registerSlave(this);
   }

   public void callbackFromMaster(Object arg) // or whatever
   {
      s.callbackFromMaster(arg);
   }
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top