2012-03-19 34 views
9

有點上下文優先:我正在用Scala編寫客戶端/服務器遊戲(第一人稱射擊遊戲),客戶端需要向服務器發送移動意圖每秒幾十次,服務器也實時發回實體狀態。在客戶端(用於圖形流動性)和服務器端都使用JBullet對這些實體進行物理模擬。每當客戶端收到來自服務器的更新時,它就會用服務器發送的地址替換它的本地狀態。當然,在同一時刻,同一臺服務器上可能會有很多客戶端。簡而言之,在這個應用程序中,通信經常發生,只有小包。斯卡拉案例類與協議在網絡上使用Akka的緩衝區

目前,我正在使用Akka的演員,通過網絡將Scala案例類簡單地發送到服務器並返回。這裏有一個例子:

sealed trait PlayerMessage 
case class PlayerMove(dir: Vector3, run: Boolean) extends PlayerMessage 
// more case classes... 

然後在客戶端上:

server ! PlayerMove(dir, run) 

在服務器上:

def receive = { 
    case pm: PlayerMessage => pm match { 
    case p @ PlayerMove(dir, run) => 
     // Move the player 
     world.playerMove(dir,run) 

     // More case tests.. 
    } 

    // Send back entity states (this in fact occurs elsewhere, asynchronously) 
    world.entities.foreach(ent => client ! ent.state())) 

    // More message testing ... 
    case _ => // ignore 
} 

凡ent.state返回EntityState:

case class BulletState(pos: Vector3, quat: Vector4, lin: Vector3, ang: Vector3) 

sealed trait EntityState 
case class EntityStatePlayer(id: Int, bullet: BulletState) extends EntityState 
// more case classes... 

這一切都工作得很好,但你可以看到有很多案例類,有時包含其他案例類,以及客戶端和服務器上的大量案例測試。

  • 我怎樣才能減少序列化,反序列化和匹配兩包大小和開銷?
  • 將使用Protobuf而不是案例類刪除我的應用程序的數據包中的脂肪?
  • 我在尋找改進這個網絡協議的錯誤地方嗎?

回答

7

阿卡使用Java序列化或谷歌Protobufs默認(參見herehere)。你可以定義你自己的序列化器,如果你認爲你可以編寫更適合你的應用程序的東西。

如果你想優化你的網絡協議,你必須打破your favorite network sniffer找出實際上來回發送。然後你可以更好地決定做什麼。但是,通常情況下,您可以手動創建更好的優化網絡協議,但當您需要進行更改時,它很可能會變得脆弱並且中斷(除非您有很多編寫網絡協議的經驗) 。

+0

我已經閱讀過這些內容,但是我還不清楚案例類是否被序列化爲Google Protobuf;我猜不是。因此,我想知道如果完全值得,可以將我的案例類轉換爲Protobufs。他們周圍的開銷可能會消除任何真正的好處; Wireshark可以爲以後提供幫助。 – gsimard 2012-03-19 19:27:18

+0

如果你的配置中有'proto =「akka.serialization.ProtobufSerializer」',Protobuf用於序列化。 – leedm777 2012-03-19 20:03:13

+4

閱讀文檔的相關部分:http://doc.akka.io/docs/akka/2.0/scala/serialization.html – 2012-03-19 21:04:34