似乎我无法从 RMI 存根中获取套接字工厂。为什么会这样?
It seems that I cannot get the socket factory from an RMI stub. Why is it so?
我正在编写一个使用 RMI 连接工厂的应用程序,以便我可以在调用远程方法之前在客户端设置超时。我想这样做,以便客户端可以在放弃和放弃调用之前等待对远程方法的调用预定的时间。
我已经创建了一个促进这种机制的套接字工厂。我使用 UnicastRemoteObject.exportObject(Remote, int, RMIServerSocketFactory, RMIClientSocetFactory)
创建远程存根,以便客户端可以将存根与自定义套接字工厂一起使用 - 两个设备都知道其 class 定义。
客户端的套接字工厂在调用服务器之前需要设置超时。客户端决定此超时的长度。我可以制作一个以这种方式工作的套接字工厂。但是,我似乎无法在客户端确保远程存根具有此自定义套接字工厂,因此我无法确保客户端套接字工厂将创建一个超时的客户端套接字。
我想知道是否有一种方法可以像我设想的那样工作 Remote.getClientFactory()
应该工作?在我看来,这是 RMI 规范未涵盖的明显功能。在没有这种方法的情况下,是否有任何使用良好的 'hack' 可以在客户端检索客户端的套接字工厂,以便可以指定超时?
即使你可以,它也不会对你有多大好处,因为你需要的不是工厂,而是将要用于拨打电话的实际套接字,这是不可预测的由于客户端连接池。
您可以尝试在每次调用之前调整 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) 开头的警告。这可能对你一点好处都没有。
我正在编写一个使用 RMI 连接工厂的应用程序,以便我可以在调用远程方法之前在客户端设置超时。我想这样做,以便客户端可以在放弃和放弃调用之前等待对远程方法的调用预定的时间。
我已经创建了一个促进这种机制的套接字工厂。我使用 UnicastRemoteObject.exportObject(Remote, int, RMIServerSocketFactory, RMIClientSocetFactory)
创建远程存根,以便客户端可以将存根与自定义套接字工厂一起使用 - 两个设备都知道其 class 定义。
客户端的套接字工厂在调用服务器之前需要设置超时。客户端决定此超时的长度。我可以制作一个以这种方式工作的套接字工厂。但是,我似乎无法在客户端确保远程存根具有此自定义套接字工厂,因此我无法确保客户端套接字工厂将创建一个超时的客户端套接字。
我想知道是否有一种方法可以像我设想的那样工作 Remote.getClientFactory()
应该工作?在我看来,这是 RMI 规范未涵盖的明显功能。在没有这种方法的情况下,是否有任何使用良好的 'hack' 可以在客户端检索客户端的套接字工厂,以便可以指定超时?
即使你可以,它也不会对你有多大好处,因为你需要的不是工厂,而是将要用于拨打电话的实际套接字,这是不可预测的由于客户端连接池。
您可以尝试在每次调用之前调整
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) 开头的警告。这可能对你一点好处都没有。