我有两个通过RMI通信的应用程序,RMI是一台从服务器(其中将有多个)和一个主服务器。

遵循良好的抽象设计,我想以一种不知道与主人交谈的方式实现从属(例如,这两个应用程序也可以在同一JVM中运行),例如) :

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

...

class Slave {

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

}

问题:标记的行 PROBLEM LINE 上面不起作用,因为我不能简单地传递这个( Slave 本身是一个 Remote 哪一个 Master 会回到)。我必须明确地做 UnicastRemoteObject.exportObject(this, 0) (或者 toStub(this) 如果是较早的导出),但这使得 Slave 班级取决于RMI,打破了设计。

此外, registerSlave 迫使我捉住 RemoteException, ,这也增加了RMI依赖性。

您建议解决这些问题?

(这也让我感到困扰,这些类必须实现远程,但我想我们只能通过抽象走得那么远)

有帮助吗?

解决方案

好吧,我这样做了:

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);
   }
  }
}

其他提示

RMI需要明确导出对象

只有它们不扩展UnicastremoteObject或可激活。如果他们这样做,他们将在施工中自动出口。

我必须明确执行UnicastremoteObject.exportObject(this,0)

不,请参见上文。

(或Tostub(此)如果之前出口)

无论tostub()是什么。有一个RemoteObject.tostub(),但是您不能打电话给它,如果您正在浪费时间。

但是您根本不必这样做。如果“此”是导出的远程对象,则可以将其作为RMI参数或结果传递。 RMI将自动替换存根。

我会对这种抽象保持警惕 - 远程服务的请求在许多方面与本地服务的请求不同 - 延迟,失败模式,重试语义。

可能是您的抽象泄漏,因为它实际上没有有效。

您的从属申请的某些部分必须准备通过RMI接收呼叫,并处理Remoteexception等。为什么不在奴隶和主人之间引入某种形式的代理,从而导致介导通信并隐藏RMI与本地问题。例如,沿着:

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);
   }
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top