【问题标题】:It seems that I cannot get the socket factory from an RMI stub. Why is it so?似乎我无法从 RMI 存根中获取套接字工厂。为什么会这样?
【发布时间】:2016-10-25 21:19:25
【问题描述】:

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

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

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

我想知道是否有一种方法可以像我设想的那样工作 Remote.getClientFactory() 应该工作?在我看来,这似乎是 RMI 规范未涵盖的一个明显功能。在没有这种方法的情况下,是否有任何常用的“hack”来检索客户端上的客户端套接字工厂,以便可以指定超时?

【问题讨论】:

    标签: java sockets rmi


    【解决方案1】:
    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) 处开始的警告。这可能对你一点好处都没有。

    【讨论】:

    • 再次感谢 EJP。我喜欢选项 4。看起来我会制作一些使用此选项的东西,然后等待更新的 RMI 规范告诉我我很顽皮。
    • 使用sun.rmi.*类已经很调皮了。我不会屏住呼吸等待 RMI 的任何变化。自 2004 年发布 1.5 以来,它根本没有发生任何事情。
    • Hmmm...RemoteStub 已弃用...我认为真实情况下的内容是为了向后兼容...我没有将此逻辑合并到我的解决方案中。我只关心我的东西是否适用于最新的 Java。
    • 这个UnicastRef2 类是唯一的专有类。看来修改后的 API 所需要做的就是在 RemoteRef 中公开客户端的套接字工厂。嗯...会很好...
    • 不幸的是,看来您是对的。我在代码中获得的套接字工厂实例似乎与 RMI 运行时使用的实例不同。我只调用一个远程方法,这个方法接受一个参数。到目前为止,RMI 对我的发展有好处,因为我可以在专注于其他事情的同时抽象出插槽机制,但 RMI 向我展示了它的局限性。因此,我决定放弃 RMI 并使用套接字本身实现我的消息传递机制。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-18
    • 1970-01-01
    • 1970-01-01
    • 2018-06-29
    相关资源
    最近更新 更多