Java 克鲁内特。马绍尔群岛共和国。尝试执行远程方法时响应超时

Java 克鲁内特。马绍尔群岛共和国。尝试执行远程方法时响应超时,java,rmi,kryo,kryonet,Java,Rmi,Kryo,Kryonet,我试图用两个独立的客户端和服务器应用程序来引导简单的KryonetRMI项目 但当我尝试执行remove方法时,它会导致: Exception in thread "main" com.esotericsoftware.kryonet.rmi.TimeoutException: Response timed out: jemmy.IJemmyCommander.run at com.esotericsoftware.kryonet.rmi.ObjectSpace$RemoteInvocation

我试图用两个独立的客户端和服务器应用程序来引导简单的KryonetRMI项目

但当我尝试执行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)
有源代码:和


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

您的项目中有几个问题:

  • 您的客户端和服务器之间必须有一个共享数据模型。您可以让服务器类保持私有,但它们必须实现客户端已知的接口
  • 当客户端调用远程对象上的方法时,它将通过线路发送一个
    InvokeMethod
    ,其中包含远程对象的标识符和方法。在服务器上,对象是lookup,方法被调用。如果接口不匹配,则会出现“对象不是声明类的实例”异常

  • 您必须为
    Kryo
    实例共享相同的配置:您的客户端和服务器必须以相同的顺序注册相同的类
  • Kryo在类名称和内部ID之间有一个映射。如果显式注册一个类,那么这个类将使用一个ID,以最小化通信量。如果在服务器上用另一个id注册同一个类,则客户端和服务器将不匹配相同的类,消息将失败

  • 在服务器中,您应该通过客户机可以调用的
    ObjectSpace
    对象进行注册
  • ObjectSpace
    是远程对象的注册表。它负责创建代理和
    InvokeMethod
    消息的处理程序。在服务器上,您应该将每个连接链接到一个或多个
    ObjectSpace

    关于您的项目

  • 创建第三个jar,其中包含客户端和服务器之间的公共接口。这个jar还可以包含一个helper类来创建
    Kryo
    实例。更容易的是,只需创建从服务器到客户端的依赖项,并注册相同的类(只需
    IJemmyCommander

  • 生成
    JemmyCommand
    实现
    IJemmyCommand

  • 在服务器上,添加:

    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());
       }
    });
    

  • 谢谢你的回复。addlistener解决了这个问题。在kryonet中没有关于它的清晰文档。但并没有必要让服务器类实现na接口(根据文档,我已经测试过了)——它通过标识符来解析。问题是:我应该关闭断开连接的客户端上的对象,还是自动处理它?你们不必使用接口,但是客户端使用的类必须为服务器所知:如果不想在客户端和服务器之间共享实现的详细信息,最好使用接口。对于第二个问题,您可以在侦听器上实现
    断开连接
    ,并进行一些清理。如果您有一个共享的
    ObjectSpace
    ,则必须调用
    removeConnection
    ,如果没有,则无需调用