2014-07-13 28 views
2

我有我的課這一小塊代碼延伸監聽器:Kryonet異常

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

每當我收到一個對象,我投它叫包帶接口方法handle()每個包實現的。然後將其添加到ConcurrentLinkedQueue以供將來處理。

不過,以後我該垃圾郵件發送UDP數據包到服務器的幾個鍵,下面的異常被拋出:

異常在線程「服務器」 java.lang.ClassCastException: com.esotericsoftware.kryonet .FrameworkMessage $ KeepAlive無法投射到012xx到com.xkynar.game.net.packet.Packet在 com.xkynar.game.net.ServerSocket.received(ServerSocket.java:70)在 com.esotericsoftware.kryonet.Server $ 1 .received(Server.java:61)at com.esotericsoftware.kryonet.Connection.notifyReceived(Connection.java:246) at 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」開始?爲什麼它進入我收到的聽衆?

請說明什麼是錯,是我的錯誤還是錯誤?

回答

0

FrameworkMessage是一個接口用於將對象標記爲在框架內部使用。從the documentation

public interface FrameworkMessage

標記接口,以表示一個消息用於由忍者框架,並且通常不可見的顯影劑。例如,這些消息僅記錄在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; 

在你的代碼,你會在上面的代碼片段,其中Packet取代SomeRequest

1

問題是Kryonet經常發送數據包我不知情的情況不關閉(在這種情況下,此報文)的連接,所以解決的辦法是做一個instanceof檢查:

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

在kryonet中,服務器一直髮送KeepAlive對象,以便客戶端不會因爲發生超時而斷開連接,因爲當客戶端在指定的時間段內沒有收到來自服務器的任何消息時發生超時,因此避免這種情況,服務器會一直髮送僅爲空對象的對象。

因此,在您收到的內容中,除了您的對象外,您還將收到KeepAlive對象數據包。

要解決此問題,您必須首先檢查一個對象是否是您嘗試將該對象轉換爲該對象的類的實例。

所以你的情況,你需要做的

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