【问题标题】:How to send and receive protobuf messages over Akka Tcp如何通过 Akka Tcp 发送和接收 protobuf 消息
【发布时间】:2016-07-16 09:17:45
【问题描述】:

我将ScalaPB 用于我的 protobuf 编译器,它为我的协议缓冲区生成 Scala 案例类、解析器和序列化程序。

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

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 案例类以及我编写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 创建连接并通过线路发送编码的消息,并测试它在到达PacketHandler 时是否被解码。

【问题讨论】:

    标签: scala akka protocol-buffers actor scalapb


    【解决方案1】:

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

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

    【讨论】:

    • 不幸的是,发送 Scala 案例类对我来说不是一个选项......使用 toByteString 的序列化是我在发送编码数据方面所寻找的。我可以匹配传入的消息吗?例如, parseFrom 期望反序列化给定的特定类型。如果我不一定知道传递的是什么类型的消息怎么办?
    • 您应该为每种消息类型提供一个带有 URI 的端点。否则,您可以将每条消息包装在父消息(具有通用类型)中,该消息在字符串中指示消息类型,在字节字段中指示实际消息,并让您的单个端点反序列化父消息,然后根据消息类型字符串。 protobuf 不会自动检测消息类型。
    • 另一种解决方案是定义一个只有一个字段的通用消息。所有其他消息类型必须具有相同的字段类型(可能是枚举或字符串)和相同的标记号,并且值应指示特定的消息类型。首先,您将使用 general-message-type 反序列化收到的消息。然后根据单个字段的值,使用指示的消息类型再次反序列化。
    • 实际上我决定使用 protobuf v2.6+ 中引入的 'oneof' 功能。这样,我使用具有“一个”子消息的父消息。现在的问题是我找不到任何关于如何使用此功能的示例。不过我快到了……
    • 我实际上想知道您是否能够澄清oneof 功能的使用...我发布了一个新问题here。供您考虑...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-06
    • 1970-01-01
    • 2019-03-31
    • 2017-05-16
    相关资源
    最近更新 更多