首先是一些上下文:我正在用 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...
这一切都工作得很好,但正如您所见,有很多案例类,有时包含其他案例类,以及客户端和服务器上的一堆案例测试。
最佳答案
Akka 默认使用 Java 序列化或 Google Protobufs(参见 here 和 here )。如果您认为可以编写更适合您的应用程序的代码,则可以定义自己的序列化程序。
如果你想优化你的网络协议(protocol),你将不得不突破 your favorite network sniffer找出实际来回发送的内容。然后你可以更好地决定做什么。
不过,一般来说,您可能可以手动创建一个更优化的网络协议(protocol),但是当您需要进行更改时,它更有可能变得脆弱和崩溃(除非您有很多编写网络协议(protocol)的经验)。
关于通过网络使用 Akka 的 Scala 案例类与 Protocol Buffer ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9775795/