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