如何通过 Akka Tcp 发送和接收 protobuf 消息

How to send and receive protobuf messages over Akka Tcp

我正在为我的 protobuf 编译器使用 ScalaPB,它为我的协议缓冲区生成 Scala 案例 classes、解析器和序列化器。

我在 .proto 文件中有一条简单的 protobuf 消息,该文件已编译为 Scala 案例 class 感谢 ScalaPB。

option java_outer_classname = "MovementProtos";

message Move {
    required string direction = 1;
    required string mode = 2;
}

此文件已编译并允许我执行以下操作:

val move = Move(direction = "up", mode = "walk")

我有一个 Akka actor 处理 TCP 连接。

class PacketHandler extends Actor {

  def receive: Receive = {
    case m: Move =>
      // successfully matched against Move case class message
    case Tcp.Received(data) =>
      // didn't match any messages
    case _: Tcp.ConnectionClosed =>
      context.stop(self)
  }
}

如果我向我的 PacketHandler 发送一条 Move protobuf 消息,它是否会成功匹配我的 Move 案例 class 我如何编写我的 receive?

如何发送 Move protobuf 消息?假设当它成功匹配 Move protobuf 消息时,它会回显它。

def receive: Receive = {
  case m: Move =>
    // successfully matched against Move case class message
    // now echo back 'm' over the wire
    sender ! Tcp.Write(???)
  ...
}

我没有客户端来测试我的 PacketHandler actor,所以我一直在使用 telnet。

知道编码的 Move 消息到底是什么样子也很有用,这样我就可以通过 telnet 创建连接并通过线路发送编码的消息,并测试它在到达 PacketHandler.

一种方法是将实例作为 Akka 消息发送。 IE。 sender ! Tcp.Write(m)。这些实例与 Scala class 的所有二进制开销一起发送。但这有点违背了使用协议缓冲区的意义。

带宽通常是系统中的 scarcest/slowest 资源之一,因此通常您会使用 rpc 的 protobuf 序列化和反序列化函数。您可以使用任何 to~ 函数(即 toByteString)进行序列化,并使用 parseFrom 进行反序列化。