我有正常运行的RMI客户端 - 服务器系统。客户端知道服务器的主机信息,因此他们可以查找并拨打电话。在第一次调用服务器时,客户端向服务器传递“自己”的远程引用,以便服务器可以进行回调。服务器维护所有连接的客户端的列表(当客户端关闭它时从服务器“取消注册”,并且有一个线程定期检查客户端是否可访问并驱逐那些不是的客户端。)
服务器上有一个图形界面(webapp的一部分),允许用户随时可视化连接的客户端。现在我被要求在此界面中显示客户端的IP地址。
我的问题:在RMI中,如果您有远程对象(存根)的远程引用,是否有一种简单的方法来确定此远程对象实际存在的主机(DNS名称或IP地址)?
注意:我可以在客户端首次连接并存储信息时使用RemoteServer.getClientHost
,或者我可以在客户端上实现返回主机信息的远程方法,但我想知道是否有内置信息以RMI方式使用远程引用。
答案 0 :(得分:1)
RMISecurityManager和UnicastRemoteObject对此没有任何说明
您可以在客户端连接时使用RemoteServer.getClientHost
。
我不相信除非在远程方法调用中传递此信息,否则无法获取此信息。
答案 1 :(得分:-1)
注意:请勿使用此功能,请参阅注释。
我有相同的要求,在GUI中显示客户端的IP地址。 在调试和分析远程对象及其子对象的类型之后,我想出了以下代码:
public static String getIpAddress(Object proxy) throws IllegalArgumentException, RemoteException, NotExpectedTypeException
{
InvocationHandler h = Proxy.getInvocationHandler(proxy);
if (h instanceof RemoteObjectInvocationHandler)
{
RemoteRef remoteRef = ((RemoteObjectInvocationHandler) h).getRef();
if (remoteRef instanceof UnicastRef)
{
Endpoint ep = ((UnicastRef) remoteRef).getLiveRef().getChannel().getEndpoint();
if (ep instanceof TCPEndpoint) { return ((TCPEndpoint) ep).getHost(); }
throw new NotExpectedTypeException(ep.getClass().getSimpleName(), "TCPEndpoint");
}
throw new NotExpectedTypeException(remoteRef.getClass().getSimpleName(), "UnicastRef");
}
throw new NotExpectedTypeException(h.getClass().getSimpleName(), "RemoteObjectInvocationHandler");
}
其中NotExpectedTypeException
是自定义的异常。
我不确定该方法的可靠性,因为它包含大量instanceof
个。
但是我在使用TCP连接的局域网中成功测试了它。