RMI網絡編程開發之三 重啓server端程序,client端無法連接

當然,你也許跟我一樣,碰到以下RefuseConnection的問題:

java.rmi.ConnectException: Connection refused to host: 146.222.94.55; nested exception is:

這個在我重啓server端的程序以後,client端執行遠程訪問時產生的。

排查原因:

1. 有可能是client端對訪問失敗的歷史,具有牴觸情緒,一旦訪問失敗,第二次嘗試就不行了。

一位老外,跟我遇到同樣的問題:

http://stackoverflow.com/questions/1477121/reconnect-rmi-client-after-server-restart

I have an RMI server and a desktop RMI client. When I restart the server, I get errors in the client. Is it possible to restart the RMI connection without restarting the client?

網友回答:When the server is terminated, you will receive a ConnectException. After that you can just use Naming.lookup to get a new server object.

我想JDK1.5以後,這個naming的方法,我已經不適用了,拋棄。

網友回答:用Spring可以很好地解決這個問題。

If you're using Spring (namely RmiProxyFactoryBean), you can simply set the property refreshStubOnConnectFailure to true and the bean will survive a restart of the server.
<property name="refreshStubOnConnectFailure" value="true" />

沒有使用spring,所以這個對我來說,沒有什麼意義

2.  針對程序本身進行debug,提出問題,爲什麼重啓會產生問題呢?

百思不得其解,後來發現,是單例模式導致的。

這個註冊服務器(getRegister)的過程,是在單例模式的類中執行的。第一次註冊後,儲存的靜態變量

(stub對象)就沒有被釋放過。所以,重啓server端程序以後,執行servlet,還是沒有重新註冊,從而導致錯誤。

正確的解決方法是,在單例模式的類中,要增加一個釋放舊的stub對象的方法,在connection發生錯誤以後就可以調用。具體實現如下:

  1. private static DataServerInterface dataServer=null
  2.  
  3. private DataServer(){ 
  4.      
  5. public static void clearOldConnection(){ 
  6.     dataServer=null

當然,在servlet調用的過程中,要記得捕獲異常,從而釋放stub對象:

  1. protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
  2.     // TODO Auto-generated method stub 
  3.     List<Weibo> weibos = null
  4.      
  5.     try
  6.     weibos = DataServer.getRmiService().getWeibos(); 
  7.  
  8.     for(Weibo item:weibos){ 
  9.         System.out.println(item.getContent()); 
  10.         response.getWriter().write(""+item.getContent()); 
  11.     }    
  12.      
  13.     }catch(Exception e){ 
  14.         System.out.println("Connection error when calling dataserver"); 
  15.         DataServer.clearOldConnection(); 
  16.         System.out.println("Due to exception,old connection has been cleaned"); 
  17.   
  18.     } 
  19.      

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章