我成功创建了一个RMI服务和客户端。我可以调用方法等。但现在我想尝试以下内容:我希望在服务上托管像LinkedList这样的标准Java对象。 此外,我想“假装”我已经拥有使用LinkedList的现有代码。我想要的是获得一个实际由服务管理的LinkedList,但我可以在本地访问,就像它是一个普通的LinkedList一样。最重要的是,我想做一些最小的日志记录,就像调用.add()一样,它在服务器上写入:“Add called”。
这不是为了生产,只是为了帮助我理解它是如何工作的!
到目前为止,我已经尝试了很多东西。最有希望的是我创建了一个扩展LinkedList并实现Remote的类。这个类试图在构造函数中使用Registry注册自己,如下所示:
try {
UnicastRemoteObject.exportObject((Remote)this);
Naming.rebind("theList", (Remote)this);
}
catch (Exception e) {
System.out.println("fail");
System.out.println(e.getMessage());
}
我必须这样做,因为我需要扩展LinkedList,因此我无法扩展UnicastRemoteObject。
我在服务器端尝试运行时获得的输出:
fail Connection refused to host: 192.168.178.27; nested exception is: java.net.ConnectException: Connection refused
在客户端:
java.lang.ClassCastException: MyList_Stub cannot be cast to java.util.LinkedList at $Proxy0.createList(Unknown Source) at RemoteProgram.main(RemoteProgram.java:27)
提前致谢!
答案 0 :(得分:2)
你要做的是非常低效,而不是一个好主意。基本上,您可以在可以序列化的方法调用中发送任何内容。如果你想要良好的性能,我建议你只有一个代表你的服务的远程对象,并作为你所需的所有服务的外观(每个远程对象产生单独的文件描述符,因此通常有很多远程对象)不是一个好主意)。此外,如果您经常添加和删除对象,则每次添加或删除元素时发送消息都不是很明智。我建议使用以下两个非常简单的方法来拥有一个远程对象:
LinkedList retrieveLinkedListByName(String);
boolean commitNewVersionOfLinkedListByName(String,LinkedList);
在应用程序启动时,您可以下载链接列表,然后定期并在应用程序退出时,您可以发回链接列表。每次在链接列表中添加或删除元素时,这应该比使用网络更有效。只要LinkedList的元素是可序列化的,你就不需要做任何魔法(比如扩展远程)就可以发送它。
答案 1 :(得分:2)
java.lang.ClassCastException: MyList_Stub cannot be cast to java.util.LinkedList
at $Proxy0.createList(Unknown Source)
at RemoteProgram.main(RemoteProgram.java:27)
LinkedList是一个具体的类,RMI与接口一起使用,因此您应该转换到客户端的List接口。
答案 2 :(得分:0)
同意其他海报,这是一种非常低效的设计。
至于您的例外情况,我不知道如何在服务器中获得“拒绝连接”并且仍然可以运行客户端。您需要发布堆栈跟踪。