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

时间:2016-03-29 01:12:49

标签: scala akka protocol-buffers actor scalapb

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

我在.proto文件中有一个简单的protobuf消息,由于ScalaPB已经编译到Scala案例类。

option java_outer_classname = "MovementProtos";

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

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

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

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

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)
  }
}

如果我向Move发送了PacketHandler个protobuf消息,它是否会成功与我的Move案例类别匹配,以及我如何撰写我的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演员,所以我一直在使用telnet。

知道编码的Move消息究竟是什么样子也很有用所以我可以通过telnet创建我的连接并通过线路发送编码消息并测试它是否在到达{{1时被解码}}

1 个答案:

答案 0 :(得分:1)

一种方法是将实例作为Akka消息发送。即。 sender ! Tcp.Write(m)。实例与Scala类的所有二进制开销一起发送。但是这种方式使得使用协议缓冲区失败了。

带宽通常是系统中最稀缺/最慢的资源之一,因此通常会对rpc使用protobuf序列化和反序列化功能。您使用任何to~函数(即toByteString)进行序列化,并使用parseFrom进行反序列化。