通过网络使用Akka的Scala案例类与协议缓冲区

时间:2012-03-19 18:30:13

标签: scala protocol-buffers actor akka case-class

首先介绍一下上下文:我在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...

这一切都运行得很好但是你可以看到有很多案例类,有时包含其他案例类,以及客户端和服务器上的一堆案例测试。

  • 如何从序列化,反序列化和匹配中减少数据包大小和开销?
  • 使用Protobuf代替案例类会减少应用程序数据包中的内容吗?
  • 我是否在寻找改进此网络协议的错误位置?

1 个答案:

答案 0 :(得分:7)

默认情况下,Akka使用Java序列化或Google Protobufs(请参阅herehere)。如果您认为可以编写针对您的应用程序更优化的内容,则可以定义自己的序列化程序。

如果您想优化网络协议,则必须突破your favorite network sniffer以找出实际来回发送的内容。然后你可以更好地决定做什么。

但是,一般情况下,您可以手动创建更好的网络协议,但是当您需要进行更改时,它更容易变脆(除非您有很多编写网络协议的经验)。