首页 >后端开发 >Golang >如何处理未知 Protobuf 消息的解组?

如何处理未知 Protobuf 消息的解组?

DDD
DDD原创
2024-12-02 16:51:16167浏览

How to Handle Unmarshaling of Unknown Protobuf Messages?

Protobuf Unmarshal:处理未知消息

在预先未知 protobuf 有效负载中的消息类型的情况下,解组到接口中{} 类型不可行,因为它需要 protobuf 消息的实现接口。

替代方法

当 protobuf 负载附带的至少部分信息可用时,例如字符串或数字,您可以使用它作为实例化的键适当的具体 protobuf 类型,然后执行解组。

处理真正的未知消息

如果不存在有关消息类型的所有信息,可以利用 protowire 包从 protobuf 有效负载的有线格式中提取有限的信息。

风险和限制

解析未知的原始消息会出现某些问题挑战:

  • 不明确的表示:线路格式可能不明确,使得很难确定某些数据结构的确切类型。
  • 损失子字段信息: 包装的消息可能会丢失有关线路类型和标签编号的上下文,从而可能限制重建原始消息的能力结构。
  • 排除非原型类型:非原型数据(例如包装的 JSON 或 XML)可能无法准确捕获。

示例实现

下面的代码提供了解析未知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中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn