2013-12-10 70 views
1

我學習Java RMI,讓自己編寫和測試這個代碼,這裏的問題是,客戶端(notificationSink類)發送消息並註冊自己與服務器但服務器(notificationSource類)不起任何作用。遠程服務器不響應客戶端的請求 - 使用Java RMI

這是RemoteThingInterface擴展Remote類:

public interface RemoteThingInterface extends Remote{ 
    public void register(NotificationSink sink) throws RemoteException; 
    public void notifySink(String text) throws RemoteException;  
} 

這是NotificationSink類:

public class NotificationSink{ 
    private String name; 
    private static String hostName = "Shine"; 
    private static int serverPort = 2712; 
    private static String text = (new Date()).toString(); 

    public NotificationSink(String name){ 
     name = this.name; 
    } 

    public static void main(String [] args){ 
     RemoteThingInterface rmiserver; 
     Registry reg; 
     System.out.println("Sending "+text+" to "+hostName+" through port "+serverPort); 

     try{ 
      reg = LocateRegistry.getRegistry(hostName, serverPort); 

      rmiserver = (RemoteThingInterface) reg.lookup("server"); 

      NotificationSink s = new NotificationSink("Eagle 1"); 

      rmiserver.register(s); 

      rmiserver.notifySink(text); 
     }catch(RemoteException ex){} catch (NotBoundException ex) { 
      ex.printStackTrace(); 
     } 
    }  
} 

這是NotificationSource類:

public class NotificationSource extends UnicastRemoteObject implements RemoteThingInterface{ 
    private ArrayList sinks = new ArrayList<>(); 
    int port; 
    Registry registry; 

    public NotificationSource() throws RemoteException{ 
     try{ 
      port = 2712; 
      registry = LocateRegistry.createRegistry(port); 
      registry.rebind("server", this); 
     }catch(RemoteException ex){ 
      ex.printStackTrace(); 
     } 
    } 

    @Override 
    public void register(NotificationSink sink) { 
     sinks.add(sink); 
    } 

    public ArrayList getSinks(){ 
     return sinks; 
    } 

    @Override 
    public void notifySink(String text){   
     System.out.println("new sink registered, he is "+getSinks().get(0)); 
     System.out.println(text); 
    } 

    public static void main(String [] args){ 
     try{ 
      NotificationSource s = new NotificationSource(); 
     }catch(Exception e){ 
      e.printStackTrace(); 
     } 
    } 
} 

請幫忙解釋一下其中i」米錯了,如何解決這個問題。我嘗試添加一些代碼來找到服務器的ArrayList大小,找出成功,但其他方法都不奏效....代碼如下所示:

加入這行來remotethinginterface:ArrayList getArray() throws RemoteException;

添加這一行到notiSource:

@Override 
    public ArrayList getArray() throws RemoteException { 
     return sinks; 
    } 

加入這行來notiSink:System.out.println(rmiserver.getArray().size());(前rmiserver.register()

回答

1

the client (notificationSink class) send a message

不,它不。

and register itself with the server

不,它不。

but the server (notificationSource class) doesn't do anything.

爲什麼要這樣呢?沒有客戶要求做任何事情。不可能有。不可能。

catch(RemoteException ex){} 

第一個主要問題在這裏。您忽略RemoteException。不要這樣做。記錄它,打印,再也不理例外,除非你真的知道你在做什麼。在這種情況下,你會因此忽略了嵌套NotSerializableException時,你們說那是被拋出register().

的第二個主要問題是NotificationSink需要兩種:

  1. 實施Serializable,如果你想讓它在執行服務器或
  2. 實現遠程接口,如果你希望它在客戶端執行延長UnicastRemoteObject,
+0

非常感謝你!!!!您剛剛提醒我一件重要的事情是可序列化的對象作爲遠程方法的參數傳遞。謝謝!!! –

+0

我想你會發現你真的想要#2在這裏,但我們會看到。 – EJP

+0

我會嘗試這兩種選項,看看有什麼與輸出發生的事情:)順便說一句,可以請你解釋爲什麼如果我改變'registry'到'Naming'它不工作?我比較,但他們沒有什麼不同。但是,當我與命名替換註冊表,我有一個錯誤:'連接refused'在行'源=(SourceInterface)命名 –

相關問題