【问题标题】:Java RMI client loss connectionJava RMI 客户端丢失连接
【发布时间】:2016-08-31 18:47:16
【问题描述】:

我正在使用 Java RMI 构建分布式应用程序。

每当代理注册到服务器时,服务器都会进行一些计算(例如,将代理添加到数组中)。并且代理不断向服务器发送活跃消息。

我想要的是,每当代理停止发送此消息或连接丢失时,服务器都会注意到并重新计算(例如,从列表中删除客户端)

最好的方法是什么?

我看到一些解决方案 ping 客户端或使用多线程。任何建议表示赞赏

【问题讨论】:

    标签: java client-server rmi


    【解决方案1】:

    有几种方法可以做到这一点,每种方法都有相关的优点和缺点。

    1) 双向生命线

    在此解决方案中,您的服务器和客户端都将具有lifeline() 方法,可以有效地永久阻塞。如果连接断开,RemoteException 将在此方法调用中立即抛出。如果客户端发起了调用,它可以尝试重新连接到服务器或退出。服务器必须维护一些逻辑,以便客户端调用的server.lifeline() 可以在客户端断开连接时返回(当服务器调用client.lifeline() 导致异常时被异常检测到),否则您将在服务器上有悬空线程阻塞永远消耗资源,直到你的服务器内存不足。

    好处:连接中断时立即通知。

    缺点:每个连接都必须在服务器和客户端上维护一个新线程,更复杂的断开逻辑。

    2) 心跳

    在这种情况下,每个客户端上仍有一个线程每隔几秒调用一次server.ping(),但服务器上只需要一个线程调用client.ping(),平均每个连接的客户端每隔几秒调用一次。如果任何ping() 调用导致异常,您就知道您已断开连接。

    好处:更简单的连接逻辑,由于管理连接状态的线程更少,服务器上消耗的资源更少。

    缺点:较慢的断开响应时间(直到 ping 调用之间的延迟),在 ping() 调用失败期间容易受到长时间 TCP 超时的影响。

    那么最好的路线是什么?

    我认为这完全取决于您的应用想要做什么。如果您需要尽快获得有关网络状态的最新绝对信息,那么第一种方法将为您提供。如果您可以容忍检测断开连接的延迟,则第二种方法更好。

    第三种选择可能是查看 RMI 对 Server/SocketFactory 实现的使用,并尝试将远程对象链接到 RMI 创建的特定套接字。我以前做过,但这不是一个快速的解决方案,尽管它可以以最少的开销为您提供两全其美的效果。

    【讨论】:

    • 不可能“将远程对象链接到特定套接字”,除非您为每个此类对象浪费地使用单独的套接字工厂。
    【解决方案2】:

    让您的服务器向每个客户端发出一个唯一的远程对象,例如实现Unreferenced 的远程会话,并让unreferenced() 方法实现实现您需要的逻辑。

    NB 在 RMI 中并没有真正意义上的“失去连接”。它的底层连接一直来来去去,受连接池的影响,在 API 级别根本没有连接。

    【讨论】:

    • 非常感谢。现在我希望每个对象中的unrefrenced() 通知服务器。我该怎么做?
    • 嗯?当没有更多客户端时,它会自动在服务器中执行。阅读 Javadoc。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-26
    • 1970-01-01
    相关资源
    最近更新 更多