首页 > 后端开发 > Golang > 正文

如何在 Go 中解组未知协议缓冲区?

Susan Sarandon
发布: 2024-11-23 08:45:15
原创
724 人浏览过

How to Unmarshal Unknown Protocol Buffers in Go?

在 Go 中解组未知协议缓冲区

使用协议缓冲区 (protobuf) 时,可能会遇到收到消息类型的情况未知。当侦听来自多个源的消息或处理动态或不可预测的消息类型时,可能会出现这种情况。

Protobuf 的默认 Unmarshal 函数需要将特定的消息类型作为参数传递,但这在消息时不可行类型未知。一种常见的方法是尝试解组到接口{}中,但 Protobuf 库不支持这种方式。

解决限制

要处理未知消息,有必要实施自定义方法。一种解决方案是使用 protowire 包,它提供对 protobuf 消息的线路表示的低级访问。

解析未知消息

以下代码片段演示了如何从未知的 protobuf 消息中解析并提取信息:

type Field struct {
    Tag
    Val
}

type Tag struct {
    Num int32
    Type protowire.Type
}

type Val struct {
    Payload interface{}
    Length int
}

func parseUnknown(b []byte) []Field {
    // ...
}
登录后复制

parseUnknown 函数迭代字节数组,使用字段并提取有关每个字段的标签和值的基本信息。

提取有效负载

提取的值有效负载可以存储在各种数据结构中,取决于字段的预期类型和内容。例如:

switch t {
case protowire.VarintType:
    v, vlen := protowire.ConsumeVarint(b[taglen:fieldlen])
case protowire.Fixed64Type:
    v, vlen := protowire.ConsumeFixed64(b[taglen:fieldlen])
// ...
}
登录后复制

限制和注意事项

这种方法有一定的局限性:

  • 歧义: protobuf 消息的线路表示可能不明确,因此很难确定值的确切类型在某些情况下。
  • 未知字段:任何未知或不受支持的字段类型都不会被解析或保留。
  • 子消息:子-消息被递归解析,但类型信息是丢失。
  • 重复字段: 未显式处理重复字段。

解析未知消息的替代方法

在大多数情况下,最好从不同的角度来处理未知消息的问题,例如如下:

  • 映射到通用消息:创建一个通用消息类型,可以封装所有可能的字段,并将未知消息映射到此通用类型。
  • 使用 Any Proto: 考虑使用 Any proto 类型来封装未知消息并保留类型信息以供以后使用

本文描述的方法提供了一种从未知的 protobuf 消息中提取基本信息的方法,但当其他选项不可行时,应将其用作后备解决方案。

以上是如何在 Go 中解组未知协议缓冲区?的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:php.cn
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板