我正在编写一个使用RMI连接工厂的应用程序,这样我就可以在调用远程方法之前在客户端设置超时。我想这样做,以便客户端可以等待远程方法的呼叫一段预定的时间,然后放弃并放弃呼叫。
我已经创建了一个促进这种机制的套接字工厂。我使用UnicastRemoteObject.exportObject(Remote, int, RMIServerSocketFactory, RMIClientSocetFactory)
创建远程存根,以便客户端可以将存根与自定义套接字工厂一起使用 - 两个设备都知道其类定义。
客户端套接字工厂需要在调用服务器之前设置超时。客户端决定超时的长度。我可以制作一个以这种方式工作的插座工厂。但是,似乎我无法在客户端上确保远程存根具有此自定义套接字工厂,因此我无法确保客户端套接字工厂将创建具有超时的客户端套接字。
我想知道是否有一种方法可以像我设想的Remote.getClientFactory()
那样工作?在我看来,这是一个显而易见的功能,并未被RMI规范所涵盖。在没有这种方法的情况下,是否有任何使用良好的黑客' hack'检索客户端上的客户端套接字工厂,以便指定超时?
答案 0 :(得分:0)
即使你可以,它也不会对你有好处,因为你需要的不是工厂,而是即将用于拨打电话的实际插座,以及由于客户端连接池而无法预测。
您可以在每次调用之前尝试调整sun.rmi.transport.tcp.responseTimeout
,但我有一种讨厌的感觉,它只在JVM的生命周期中读过一次。
否则,您可以为每个远程对象使用不同的套接字工厂,为每个远程接口使用不同的远程对象,并为每个远程方法使用不同的远程接口,以便每个套接字工厂与唯一的远程方法唯一关联。 ..然后根据需要为每个工厂分配一个套接字读取超时,但它仍然是服务器端;它会对连接池造成严重破坏。
或者,如果你想要非官方的引擎盖可能 - 不工作 - 下一个版本不合规don't use sun.* classes顽皮版本:
RemoteRef remoteRef;
if (stub instanceof RemoteStub)
{
remoteRef = ((RemoteStub)stub).getRef();
}
else
{
// dynamic proxy
RemoteObjectInvocationHandler roih = (RemoteObjectInvocationHandler)java.lang.reflect.Proxy.getInvocationHandler(stub);
remoteRef = roih.getRef();
}
if (remoteRef instanceof sun.rmi.server.UnicastRef2)
{
// JRMP stub with client socket factory.
// NB UnicastRef.getLiveRef() was added somewhere between 1.3 and 1.6.
// Previously it was only obtainable via reflection.
RMIClientSocketFactory csf = ((sun.rmi.server.UnicastRef2)remoteRef).getLiveRef().getClientSocketFactory();
// YOUR CODE GOES HERE
// Note that 'csf' can still be null here, if you exported the remote object with an *explicitly null* client socket factory parameter.
}
然而请注意我在(1)开始时的警告。这可能对你没什么好处。