【问题标题】:Kryonet Exception when casting received Object (Bug?)投射收到的对象时出现 Kryonet 异常(错误?)
【发布时间】:2015-07-06 04:59:53
【问题描述】:

我的班级中有一小段代码扩展了监听器:

@Override
public void received(Connection connection, Object object)
{
    Packet packet = (Packet) object;
    server.addPacket(new ClientPacket(connection.getID(), packet));
}

每当我收到一个对象时,我都会将其转换为一个名为 Packet 的接口,并使用每个数据包都实现的方法 handle()。然后我将它添加到 ConcurrentLinkedQueue 以供将来处理。

尽管如此,在我向服务器发送 UDP 数据包的几个密钥发送垃圾邮件后,仍会引发以下异常:

线程“服务器”java.lang.ClassCastException 中的异常: com.esotericsoftware.kryonet.FrameworkMessage$KeepAlive 无法强制转换 到 com.xkynar.game.net.packet.Packet 在 com.xkynar.game.net.ServerSocket.received(ServerSocket.java:70) 在 com.esotericsoftware.kryonet.Server$1.received(Server.java:61) 在 com.esotericsoftware.kryonet.Connection.notifyReceived(Connection.java:246) 在 com.esotericsoftware.kryonet.Server.update(Server.java:208) 在 com.esotericsoftware.kryonet.Server.run(Server.java:356) 在 java.lang.Thread.run(未知来源)

异常发生在演员表中,即:

Packet packet = (Packet) object;

这怎么可能? “FrameworkMessage$KeepAlive”到底是什么?为什么它会进入我收到的听众?

请解释一下出了什么问题,是我的错误还是错误?

【问题讨论】:

    标签: exception casting kryonet


    【解决方案1】:

    问题是 Kryonet 经常在我不知情的情况下发送数据包以不关闭连接(在这种情况下为 KeepAlive 数据包),因此解决方案是进行 instanceof 检查:

    @Override
    public void received(Connection connection, Object object)
    {   
        if(object instanceof Packet)
            server.addPacket(new ClientPacket(connection.getID(), (Packet) object));
    }
    

    【讨论】:

      【解决方案2】:

      FrameworkMessage 是一个接口,用于将对象标记为在框架内部使用。来自the documentation

      public interface FrameworkMessage

      标记接口,表示一条消息被 Ninja 框架使用,并且通常对开发人员是不可见的。例如,这些消息仅记录在 Log.LEVEL_TRACE 级别。

      可以肯定地假设您的代码可能不是服务器的唯一侦听器。解决方案是在运行时检查object 的身份。这在kryonet readme 中有说明:

      server.addListener(new Listener() {
          public void received (Connection connection, Object object) {
              if (object instanceof SomeRequest) {
                  SomeRequest request = (SomeRequest)object;
      

      在您的代码中,您将在上述 sn-p 中将 SomeRequest 替换为 Packet

      【讨论】:

        【解决方案3】:

        在 kryonet 中,服务器不断发送KeepAlive 对象,以便客户端不会由于超时而断开连接,因为当客户端在规定的时间段内没有收到来自服务器的任何消息时会发生超时,因此为避免这种情况,服务器会不断发送 KeepAlive 对象,这些对象只是空对象。

        因此,在您收到的内容中,除了您的对象之外,您还将收到KeepAlive 对象数据包。

        要解决此问题,您必须首先检查对象是否是您尝试将对象转换为的类的实例。

        所以你需要这样做

         if(object instanceof Packet)
                server.addPacket(new ClientPacket(connection.getID(), (Packet) object));
        

        【讨论】:

          猜你喜欢
          • 2019-01-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-12-29
          • 1970-01-01
          • 1970-01-01
          • 2014-03-07
          • 2013-03-04
          相关资源
          最近更新 更多