3

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

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

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)

有源代码:服务器客户端

如何让它工作?它应该在服务器控制台上打印“运行”。

4

1 回答 1

3

您的项目中有多个问题:

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

当客户端调用远程对象上的方法时,它将通过线路发送InvokeMethod带有远程对象标识符和方法的 an。在服务器上,查找对象并调用方法。如果接口不匹配,您将收到“对象不是声明类的实例”异常。

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

Kryo 在类名和内部 ID 之间有一个映射。如果你显式注册一个类,那么这个类将使用一个 id,以最小化流量。如果您在服务器上使用另一个 id 注册相同的类,则客户端和服务器将不匹配相同的类,并且消息将失败。

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

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

在您的项目上

  1. 创建第三个 jar,其中包含客户端和服务器之间的公共接口。这个 jar 还可以包含一个帮助类来创建一个Kryo实例。更容易,只需创建从服务器到客户端的依赖项,并注册相同的类(仅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());
       }
    });
    
于 2016-02-21T16:21:09.640 回答