2012-03-19 12 views
9

Un poco de contexto primero: estoy escribiendo un juego cliente/servidor en Scala (en primera persona como tirador), donde el cliente debe enviar intenciones de movimiento al servidor unas pocas docenas de veces por segundo y el servidor envía estados de la entidad de vuelta, en tiempo real también. Hay simulación física de estas entidades usando JBullet tanto en el cliente (para la fluidez gráfica) como en el lado del servidor. Cada vez que un cliente recibe actualizaciones del servidor, reemplaza sus estados locales con los que el servidor envió. Puede haber muchos clientes en el mismo servidor en un momento dado, por supuesto. En resumen, en esta aplicación la comunicación ocurre a menudo, con pequeños paquetes.Scala Case Classes vs. Protocol Buffers with Akka en la red

Por el momento, estoy usando a los actores de Akka para enviar ingenuamente clases de casos de Scala a través de la red al servidor y viceversa. Aquí está un ejemplo:

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

A continuación, en el cliente:

server ! PlayerMove(dir, run) 

En el servidor:

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 
} 

Dónde ent.state devuelve 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... 

Todo está funcionando bastante bien, pero como puedes ver hay muchas clases de casos, que a veces contienen otras clases de casos, y un montón de pruebas de casos tanto en el cliente como en el servidor.

  • ¿Cómo puedo reducir tanto el tamaño del paquete como la sobrecarga de serialización, deserialización y coincidencia?
  • ¿Usaría Protobuf en lugar de clases de casos para eliminar la grasa de los paquetes de mi aplicación?
  • ¿Estoy buscando el lugar incorrecto para mejorar este protocolo de red?

Respuesta

7

Akka utiliza la serialización de Java o Google Protobufs por defecto (ver here y here). Puede definir sus propios serializadores si cree que puede codificar algo que esté más optimizado para su aplicación.

Si desea optimizar su protocolo de red, tendrá que abrir your favorite network sniffer para averiguar qué se está enviando en realidad. Entonces puedes decidir mejor qué hacer.

En general, sin embargo, es probable que pueda crear un protocolo de red mejor optimizado con la mano, pero es más probable que sean frágiles y se rompen cuando se necesita hacer cambios (a menos que tengas una gran cantidad de protocolos de red experiencia de escritura) .

+0

Ya había leído esto, pero aún no estoy seguro si una clase de caso se serializa como un Protobuf de Google o no; Yo diría que no. Por lo tanto, me gustaría saber qué puedo hacer para transformar mis clases de casos en Protobufs, si vale la pena. Los gastos generales a su alrededor pueden eliminar cualquier beneficio real; Wireshark puede ayudar para el futuro. – gsimard

+0

Si tiene 'proto =" akka.serialization.ProtobufSerializer "' en su configuración, Protobuf se usa para la serialización. – leedm777

+4

Lea la sección correspondiente de los documentos: http://doc.akka.io/docs/akka/2.0/scala/serialization.html –

Cuestiones relacionadas