首先是一些上下文:我正在用 Scala 编写一个客户端/服务器游戏(类似第一人称射击游戏),其中客户端需要每秒向服务器发送几十次移动意图,服务器将实体状态发送回来,在也是实时的。在客户端(用于图形流动性)和服务器端都使用 JBullet 对这些实体进行物理模拟。每当客户端从服务器接收到更新时,它都会用服务器发送的状态替换其本地状态。当然,在给定时刻,同一台服务器上可能有许多客户端。简而言之,在这个应用程序中,通信经常发生,带有小数据包。
目前,我正在使用 Akka 的 actor 天真地通过网络将 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 而不是案例类会从我的应用程序的数据包中减少脂肪吗?
- 我是否在寻找改进此网络协议的错误位置?