【问题标题】:Protocol Buffers between two different languages两种不同语言之间的协议缓冲区
【发布时间】:2020-03-26 21:59:42
【问题描述】:

我们将 Golang 和 .NET Core 用于我们的相互通信微服务基础架构。 服务中的所有数据都基于我们创建的 Protobuffs 协议。 这是我们的一个 Protobuffs 的示例:

syntax = "proto3";
package Protos;
option csharp_namespace = "Protos";
option go_package="Protos";
message EventMessage {
    string actionType = 1;
    string payload = 2;
    bool auditIsActive = 3;
}

Golang 运行良好,服务根据需要生成内容并将其发送到 SQS 队列,一旦发生这种情况,.NET 核心服务将获取数据并尝试对其进行序列化。

以下是 SQS 消息示例的内容:

{"@type":"type.googleapis.com/Protos.EventMessage","actionType":"PushPayload","payload":"<<INTERNAL>>"}

但是我们得到一个例外,说电线类型没有定义如下:

Google.Protobuf.InvalidProtocolBufferException: Protocol message contained a tag with an invalid wire type.
   at Google.Protobuf.UnknownFieldSet.MergeFieldFrom(CodedInputStream input)
   at Google.Protobuf.UnknownFieldSet.MergeFieldFrom(CodedInputStream input)
   at Google.Protobuf.UnknownFieldSet.MergeFieldFrom(UnknownFieldSet unknownFields, CodedInputStream input)
   at Protos.EventMessage.MergeFrom(CodedInputStream input) in /Users/maordavidzon/projects/github_connector/GithubConnector/GithubConnector/obj/Debug/netcoreapp3.0/EventMessage.cs:line 232
   at Google.Protobuf.MessageExtensions.MergeFrom(IMessage message, Byte[] data, Boolean discardUnknownFields, ExtensionRegistry registry)
   at Google.Protobuf.MessageParser`1.ParseFrom(Byte[] data)

两个服务中的 Proto 文件完全相同。

我们是否需要添加任何潜在的缺失选项或属性?

【问题讨论】:

  • 最可能的原因是二进制有效负载处理不正确;你有一个示例二进制有效负载吗?请注意,您可以使用protogen.marcgravell.com/decode 验证有效负载 - 破坏二进制有效负载的经典方法包括:1) 通过文本编码向后运行将其“编码”(有意使用引号)将其转换为文本(您应该使用 base-64或十六进制等,如果您需要将其作为文本传递,而不是反向文本编码),2)使用 C 样式字符串(nul 终止)API(不要),或 3)截断/过度填充有效负载( protobuf 不会自动终止)
  • 从问题来看,您似乎在 JSON 中传递 protobuf,所以:我的钱在上面的第一个选项上:我很高兴推测您已经将它编码为文本(对于JSON) 不正确。直到您在调用ParseFrom 之前可以恢复到原始字节,所有其他考虑都是没有意义的
  • 哦! (灯亮了)你使用的是 JSON 版本的 protobuf 吗?如果是这样的话;是的,您需要使用 JSON 解析 API; protobuf 有两种格式——通常,人们指的是二进制格式,ParseFrom(byte[]) 是二进制格式。如果您使用 JSON 数据格式,则需要使用 JSON 解析 API。有ParseFromJson 或类似的吗?还是需要string 的?编辑:检查文档,ParseJson:developers.google.com/protocol-buffers/docs/reference/csharp/…

标签: go .net-core protocol-buffers grpc protobuf-net


【解决方案1】:

基本上有两种可能的情况,或者您为 .NET 和 GoLang 生成的 protos 文件不在同一版本中,或者您的数据在 GoLang 和 .NET 应用程序之间传输时已损坏。

Protobuf 是一个二进制协议,请检查您是否有任何 http 过滤器或任何其他可以更改传入或传出字节流的东西。

【讨论】:

  • “Protobuf 是一个二进制协议”——我们通常认为它是这样的(我的 protobuf 库只支持这种模式),但是 一个 JSON 变体,它看起来就像 OP 使用 JSON 变体一样。
【解决方案2】:

看起来您使用的是 JSON 格式而不是二进制格式。在这种情况下,you want ParseJson(string json), not ParseFrom(byte[] data)

注意:二进制格式更有效,如果这对您很重要的话。它还对 protobuf 库/工具有更好的支持。

【讨论】:

    猜你喜欢
    • 2015-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-18
    • 2021-12-19
    • 2011-11-15
    • 1970-01-01
    相关资源
    最近更新 更多