克里奥内特。 RMI。尝试执行远程方法时响应超时

Kryonet. RMI. Response timed out while trying to execute remote method

我正在尝试 bootstrap 使用两个独立的客户端和服务器应用程序的简单 kryonet RMI 项目。

但是当我尝试执行删除方法时 - 它会导致:

Exception in thread "main" com.esotericsoftware.kryonet.rmi.TimeoutException: Response timed out: jemmy.IJemmyCommander.run
at com.esotericsoftware.kryonet.rmi.ObjectSpace$RemoteInvocationHandler.invoke(ObjectSpace.java:408)
at com.sun.proxy.$Proxy0.run(Unknown Source)
at jemmy.dummy.client.RunClient.main(RunClient.java:29)

有源码:server and client.

如何让它发挥作用?它应该在服务器控制台上打印 "Run"。

您的项目中有几个问题:

  1. 您的客户端和服务器之间必须有共享数据模型。您可以将服务器 classes 设为私有,但它们必须实现您的客户端已知的接口

当客户端调用远程对象的方法时,它会通过网络发送一个 InvokeMethod,其中包含远程对象的标识符和一个方法。在服务器上,查找对象并调用方法。如果接口不匹配,您将得到一个 "object is not an instance of the declaring class" 异常。

  1. 您的 Kryo 实例必须共享相同的配置:您的客户端和服务器必须以相同的顺序注册相同的 classes

Kryo 在 classes 名称和内部 ID 之间有一个映射。如果您显式注册一个 class,那么这个 class 将使用一个 id,以最大程度地减少流量。如果你在你的服务器上注册相同的 class 与另一个 id,那么客户端和服务器将不会匹配相同的 classes,消息将失败。

  1. 在您的服务器中,您应该通过一个 ObjectSpace 对象注册,该对象可以被您的客户端调用

ObjectSpace 是远程对象的注册表。它负责创建代理和 InvokeMethod 消息的处理程序。在服务器上,你应该link每个连接到一个或几个ObjectSpace

关于你的项目 :

  1. 创建第三个 jar,其中包含客户端和服务器之间的通用接口。这个 jar 还可以包含一个助手 class 来创建一个 Kryo 实例。更容易的是,只需创建从服务器到客户端的依赖项,并注册相同的 classes(只需要 IJemmyCommander

  2. 使JemmyCommand实现IJemmyCommand

  3. 在您的服务器上,添加:

    server.addListener(new Listener() {
       @Override
       public void connected(Connection connection) {
          // 44 is the identifier of the JemmyCommander, referenced by a client
          new ObjectSpace(connection).register(44, new JemmyCommander());
       }
    });