2012-03-19 2 views
9

Немного контекста: я пишу клиент/серверную игру в Scala (шутер от первого лица), где клиенту необходимо отправить намерения движения на сервер несколько десятков раз в секунду, и сервер отправляет состояния сущностей обратно в режиме реального времени. Существует физическое моделирование этих объектов с использованием JBullet как на клиенте (для графической гибкости), так и на стороне сервера. Всякий раз, когда клиент получает обновления с сервера, он заменяет свои локальные состояния теми, которые отправил сервер. Конечно, может быть много клиентов на одном сервере в данный момент. Короче говоря, в этом приложении общение происходит часто, с небольшими пакетами.Scala Case Classes vs. Protocol Buffers с 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 вместо классов case вырезать жир из пакетов моего приложения?
  • Я искал неправильное место для улучшения этого сетевого протокола?

ответ

7

По умолчанию в программе Akka используется сериализация Java или Google Protobufs (см. here и here). Вы можете определить свои собственные сериализаторы, если вы считаете, что можете скопировать то, что более оптимизировано для вашего приложения.

Если вы хотите оптимизировать свой сетевой протокол, вам нужно будет вырваться your favorite network sniffer, чтобы узнать, что на самом деле отправляется туда и обратно. Тогда вы можете лучше решить, что делать.

В общем, вы, вероятно, можете создать лучший оптимизированный сетевой протокол вручную, но он, скорее всего, будет хрупким и сломается, когда вам нужно внести изменения (если у вас нет большого опыта написания сетевых протоколов) ,

+0

Я уже прочитал их, но я все еще неясно, если класс case сериализуется как Google Protobuf или нет; Думаю, нет. Поэтому я хотел бы узнать, что я могу сделать, чтобы превратить классы моего дела в Protobufs, если это вообще того стоит. Накладные расходы вокруг них могут устранить любую реальную выгоду; Wireshark может помочь позже. – gsimard

+0

Если у вас есть 'proto =" akka.serialization.ProtobufSerializer "' в вашей конфигурации, Protobuf используется для сериализации. – leedm777

+4

Прочтите соответствующий раздел документации: http://doc.akka.io/docs/akka/2.0/scala/serialization.html –