Protobuf Unmarshal:处理未知消息
在预先未知 protobuf 有效负载中的消息类型的情况下,解组到接口中{} 类型不可行,因为它需要 protobuf 消息的实现接口。
替代方法
当 protobuf 负载附带的至少部分信息可用时,例如字符串或数字,您可以使用它作为实例化的键适当的具体 protobuf 类型,然后执行解组。
处理真正的未知消息
如果不存在有关消息类型的所有信息,可以利用 protowire 包从 protobuf 有效负载的有线格式中提取有限的信息。
风险和限制
解析未知的原始消息会出现某些问题挑战:
示例实现
下面的代码提供了解析未知protobuf的示例message:
package main import ( "fmt" "github.com/jhump/protoreflect/desc" "github.com/jhump/protoreflect/internal/strategy" "github.com/jhump/protoreflect/protopath" ) // Field represents an individual element parsed from an unknown protobuf message. type Field struct { Tag Tag Val interface{} Length int } // Tag represents a field tag with its number and wire type. type Tag struct { Num int32 Type int } // parseUnknown parses an unknown protobuf message. func parseUnknown(b []byte, parentMsg *desc.MessageDescriptor) []Field { parser := &protowireParser{msg: parentMsg, buf: b} return parser.run() } type protowireParser struct { msg *desc.MessageDescriptor buf []byte } const wireTypeMask = 0x7 func (p *protowireParser) run() (fields []Field) { for len(p.buf) > 0 { field, l, err := protowire.ConsumeField(p.buf) if err != nil || l < 1 { log.Printf("Error parsing field: %v", err) p.buf = nil return } tag := Tag{Num: field.Tag, Type: field.WireType & wireTypeMask} var v interface{} switch field.WireType & wireTypeMask { // ... handle different wire types } fields = append(fields, Field{Tag: tag, Val: v, Length: l}) p.buf = p.buf[l:] } return fields }
结论
解析真正未知的 protobuf 消息是一项复杂的任务,但是通过利用 protowire 包,您可以提取可能足够的有限信息针对您的具体场景。请记住,此方法不适合准确表示至关重要的生产级应用程序。
以上是如何处理未知 Protobuf 消息的解组?的详细内容。更多信息请关注PHP中文网其他相关文章!