铸造收到对象时的Kryonet异常(Bug?)

时间:2014-07-13 06:06:30

标签: exception casting kryonet

我的班级中有一小段代码,它扩展了Listener:

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

每当我收到一个Object时,我就把它转换到一个名为Packet的接口,每个数据包实现一个方法句柄()。然后我将它添加到ConcurrentLinkedQueue以供将来处理。

但是,在我发送了几个将UDP数据包发送到服务器的密钥之后,抛出了以下异常:

  

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

演员表中发生异常,即:

Packet packet = (Packet) object;

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

请解释有什么问题,是我的错误还是错误?

3 个答案:

答案 0 :(得分:1)

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

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

答案 1 :(得分:0)

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

  

public interface FrameworkMessage

     

Marker接口表示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;

在您的代码中,您将SomeRequest替换为上述代码段中的Packet

答案 2 :(得分:0)

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

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

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

所以在你的情况下你需要做

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