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