似乎我无法从RMI存根获取套接字工厂。为什么会这样?

时间:2016-06-23 13:39:04

标签: java sockets rmi

我正在编写一个使用RMI连接工厂的应用程序,这样我就可以在调用远程方法之前在客户端设置超时。我想这样做,以便客户端可以等待远程方法的呼叫一段预定的时间,然后放弃并放弃呼叫。

我已经创建了一个促进这种机制的套接字工厂。我使用UnicastRemoteObject.exportObject(Remote, int, RMIServerSocketFactory, RMIClientSocetFactory)创建远程存根,以便客户端可以将存根与自定义套接字工厂一起使用 - 两个设备都知道其类定义。

客户端套接字工厂需要在调用服务器之前设置超时。客户端决定超时的长度。我可以制作一个以这种方式工作的插座工厂。但是,似乎我无法在客户端上确保远程存根具有此自定义套接字工厂,因此我无法确保客户端套接字工厂将创建具有超时的客户端套接字。

我想知道是否有一种方法可以像我设想的Remote.getClientFactory()那样工作?在我看来,这是一个显而易见的功能,并未被RMI规范所涵盖。在没有这种方法的情况下,是否有任何使用良好的黑客' hack'检索客户端上的客户端套接字工厂,以便指定超时?

1 个答案:

答案 0 :(得分:0)

  1. 即使你可以,它也不会对你有好处,因为你需要的不是工厂,而是即将用于拨打电话的实际插座,以及由于客户端连接池而无法预测。

  2. 您可以在每次调用之前尝试调整sun.rmi.transport.tcp.responseTimeout,但我有一种讨厌的感觉,它只在JVM的生命周期中读过一次。

  3. 否则,您可以为每个远程对象使用不同的套接字工厂,为每个远程接口使用不同的远程对象,并为每个远程方法使用不同的远程接口,以便每个套接字工厂与唯一的远程方法唯一关联。 ..然后根据需要为每个工厂分配一个套接字读取超时,但它仍然是服务器端;它会对连接池造成严重破坏。

  4. 或者,如果你想要非官方的引擎盖可能 - 不工作 - 下一个版本不合规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)开始时的警告。这可能对你没什么好处。