2015-08-28 25 views
0

所以我目前有很多的代碼,它很難將它全部分解成一個SSCCE,但也許我會稍後嘗試這樣做,如果有必要的話。如何在程序關閉並重新啓動時恢復RMI通信,而另一個仍在Java中運行?

無論如何,這裏的要點是:我有兩個通過RMI進行通信的進程。有用。但是,如果主機進程(JobViewer)退出並且返回客戶端進程(Job)生命週期內的所有通信,我希望能夠繼續。

目前,每次作業啓動時,我都會將綁定名稱保存到文件中,並且JobViewer在啓動時打開此文件。它效果很好,正確的綁定名稱起作用。但是,每次嘗試恢復與作業的通信時,我都會收到一個NotBoundException,我知道在JobViewer重新啓動時,它仍然在運行。

我JobViewer實現了以下方法遠程擴展的接口:

public void registerClient(String bindedName, JobStateSummary jobSummary) throws RemoteException, NotBoundException; 
public void giveJobStateSummary(JobStateSummary jobSummary) throws RemoteException; 
public void signalEndOfClient(JobStateSummary jobSummary) throws RemoteException; 

我的工作也實現了不同的界面,使用以下方法遠程擴展:

public JobStateSummary getJobStateSummary() throws RemoteException; 
public void killRemoteJob() throws RemoteException; 
public void stopRemoteJob() throws RemoteException; 
public void resumeRemoteJob() throws RemoteException; 

我如何做到這一點?下面是我的一些當前代碼inits的RMI如果它可以幫助...

JobViewer方:

private Registry _registry; 
// Set up RMI 
_registry = LocateRegistry.createRegistry(2002); 
_registry.rebind("JOBVIEWER_SERVER", this); 

招聘方:

private NiceRemoteJobMonitor _server; 

Registry registry = LocateRegistry.getRegistry(hostName, port); 
registry.rebind(_bindedClientName, this); 
Remote remoteServer = registry.lookup(masterName); 

_server = (NiceRemoteJobMonitor)remoteServer; 
_server.registerClient(_bindedClientName, _jobStateSummary); 

回答

-1

我的解決辦法是讓招聘坪JobViewer每隔一段時間:

while (true) { 

    try { 

     _server.ping(); 
     // If control reaches here we were able to successfully ping the job monitor. 

    } catch (Exception e) { 

     System.out.println("Job lost contact with the job monitor at " + new Date().toString() + " ..."); 

     // If control reaches we were unable to ping the job monitor. Now we will loop until it presumably comes back to life. 
     boolean foundServer = false; 
     while (!foundServer) { 

     try { 

      // Attempt to register again. 
      Registry registry = LocateRegistry.getRegistry(_hostName, _port); 
      registry.rebind(_bindedClientName, NiceSupervisor.this); 
      Remote remoteServer = registry.lookup(_masterName); 
      _server = (NiceRemoteJobMonitor)remoteServer; 
      _server.registerClient(_bindedClientName, _jobStateSummary); 

      // Ping the server for good measure. 
      _server.ping(); 

      System.out.println("Job reconnected with the job monitor at " + new Date().toString() + " ..."); 

      // If control reaches here we were able to reconnect to the job monitor and ping it again. 
      foundServer = true; 

     } catch (Exception x) { 

      System.out.println("Job still cannot contact the job monitor at " + new Date().toString() + " ..."); 

     } 

     // Sleep for 1 minute before we try to locate the registry again. 
     try { 
      Thread.currentThread().sleep(PING_WAIT_TIME); 
     } catch (InterruptedException x) { 

     } 

    } // End of endless loop until we find the server again. 

    } 

    // Sleep for 1 minute after we ping the server before we try again. 
    try { 
     Thread.currentThread().sleep(PING_WAIT_TIME); 
    } catch (InterruptedException e) { 

    } 

    } // End of endless loop that we never exit. 
+0

濫殺濫傷重複上任意的異常不能被推薦作爲解決方案。您應該重複大多數但不是全部RemoteExceptions。各種其他異常(如NOE)會在您的代碼中指示錯誤,而不是重試的時機。我再重複一遍,客戶端根本不需要將自己綁定到註冊表。 – EJP

0

每次都遇到一個NotBoundException我嘗試恢復與作業相關的通信,但在JobViewer重新啓動時,事實上它仍在運行。

只有當JobViewer在啓動時沒有重新綁定時,纔會發生這種情況。更常見的情況是,當你使用一個陳舊的存根,即遠端對象已經退出的存根時,你會得到一個NoSuchObjectException。在這種情況下,您應該重新獲取存根,即重做lookup()

爲什麼客戶端自己綁定到註冊表?如果您想註冊回調,只需將this傳遞給registerClient()方法而不是綁定名稱,並相應地調整其簽名(使用客戶端的遠程接口作爲參數類型)。無需讓服務器對客戶端註冊表進行查找。根本不需要客戶端註冊表。

相關問題