2012-03-19 8 views
9

Un po 'di contesto prima: sto scrivendo un gioco client/server in Scala (in prima persona tipo sparatutto), dove il client ha bisogno di inviare intenzioni di movimento al server poche decine di volte al secondo e il server invia nuovamente gli stati delle entità, anche in tempo reale. Esiste una simulazione fisica di queste entità usando JBullet sia sul client (per fluidità grafica) che sul lato server. Ogni volta che un client riceve aggiornamenti dal server, sostituisce i suoi stati locali con quelli inviati dal server. Naturalmente ci possono essere molti client sullo stesso server in un dato momento. In breve, in questa applicazione la comunicazione avviene spesso, con piccoli pacchetti.Classi Case Scala e Protocolli Buffer con Akka in rete

Al momento, sto utilizzando gli attori di Akka per inviare in modo ingenuo classi di casi Scala sulla rete al server e viceversa. Ecco un esempio:

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

Poi sul client:

server ! PlayerMove(dir, run) 

Sul server:

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 
} 

Dove ent.state restituisce un 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... 

Funziona tutto molto bene ma come puoi vedere ci sono un sacco di classi di casi, a volte contenenti altre classi di casi, e un sacco di case test sia sul client che sul server.

  • Come è possibile ridurre la dimensione del pacchetto e l'overhead da serializzazione, deserializzazione e corrispondenza?
  • L'utilizzo di Protobuf invece delle classi case ha eliminato il grasso dai pacchetti dell'applicazione?
  • Sto guardando nel punto sbagliato per migliorare questo protocollo di rete?

risposta

7

Akka utilizza la serializzazione Java o Google Protobufs per impostazione predefinita (vedere here e here). È possibile definire i propri serializzatori, se si pensa di poter codificare qualcosa che sia più ottimizzato per la propria applicazione.

Se si desidera ottimizzare il protocollo di rete, è necessario scoppiare your favorite network sniffer per scoprire cosa viene effettivamente inviato avanti e indietro. Quindi puoi decidere meglio cosa fare.

In generale, tuttavia, è possibile creare probabilmente un protocollo di rete ottimizzato a mano, ma è più probabile che si crei fragilità e si interrompa quando è necessario apportare modifiche (a meno che non si abbia molta esperienza nella scrittura dei protocolli di rete) .

+0

Avevo già letto questi, ma non sono ancora chiaro se una classe di casi è serializzata come Google Protobuf o no; Direi di no. Perciò mi piacerebbe scoprire cosa posso ottenere trasformando le mie case history in Protobuf, se ne vale la pena. Il sovraccarico attorno a loro può rimuovere qualsiasi beneficio reale; Wireshark può aiutare per il futuro. – gsimard

+0

Se si ha 'proto =" akka.serialization.ProtobufSerializer "' nella propria configurazione, il Protobuf viene utilizzato per la serializzazione. – leedm777

+4

Leggi la sezione pertinente dei documenti: http://doc.akka.io/docs/akka/2.0/scala/serialization.html –