Java RMI - 将客户端变成服务器

5
如果我想在我的RMI应用程序中启用“双向”通信(即允许服务器调用客户端的方法以及客户端调用服务器的方法),那么最简单的方法是将客户端也变成一个远程类吗?
另外,如果我打算将客户端实例作为方法参数传递给服务器,那么我是否正确地认为不需要将“客户端类”添加到rmiregistry中?
最后一个问题,我的所有类是否仍然需要编译在同一个位置?例如,我可以在两个完全独立的机器上编译服务器和客户端,并期望它们能够正常通信吗?
*编辑*
还有一个问题,我的问题提到了我的客户端接口(IClient):它有一个数组列表(所以我有ArrayList < IClient>)来存储客户端的新实例,以便服务器可以跟踪注册的客户端。当我尝试在不同的机器上编译服务器时,它会抱怨找不到IClient - 很明显,因为IClient在客户端机器上。我该如何解决这个问题?
3个回答

3

你的所有假设都是正确的。

你不必将可远程调用的客户端类添加到RMI注册表中,但仍然需要导出它们。

编译时唯一的注意事项是必须使用相同版本的Java和相同的编译器设置(至少影响RMI存根生成的设置)。


你不应该使用RMI存根,它们已经很多年没必要了。而且,就大部分而言,JDK 5和6通过RMI进行通信是没有问题的(在发布的某个版本的JDK 6中存在一些问题,但已经修复)。 - jtahlborn
@jtahlborn 感谢您的纠正,我上次使用RMI确实是在1.4版本之前,但重点只是以类似的方式编译它们。 - biziclop

3
如果您的客户端或服务器在未来部署中将位于防火墙后,请远离RMI。这会给您带来麻烦,特别是如果您希望服务器调用客户端。
以下是两个替代方案,对我们非常有效:
- 让客户端调用服务器,并使服务器阻塞调用,直到客户端有数据可用。这将使用一个线程每个客户端(如果您不使用NIO),但易于实现。偶尔返回null以防止长时间运行的客户端调用被防火墙关闭(根据防火墙配置)。 - 如果您想要漂亮的Java接口,请考虑非常轻量级、基于HTTP运行并且不涉及RMI注册表或类似东西的Hessian。 - 如果您打算向其他客户端开放服务器端,则Hessian仍然是一个不错的选择,但如果扩展是一个问题,请考虑RESTful架构风格。

0
关于您的最后一个问题,远程接口类及其所依赖的所有类以及递归地直到闭包必须存在于两个主机上。

那么 IClient 接口必须在编译时对服务器可用吗?我认为 RMI 的重点是可以动态加载它从未见过的类(或者我哪里理解错了)? - richzilla
在编译时和运行时,RMI的代码库特性的重点是远程接口中实现接口或抽象类的类可以动态加载。然而,远程接口本身及其依赖项在这个意义上是静态的。 - user207421

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接