>백엔드 개발 >Golang >Go에서 알 수 없는 Protobuf 메시지를 어떻게 언마샬링하나요?

Go에서 알 수 없는 Protobuf 메시지를 어떻게 언마샬링하나요?

Linda Hamilton
Linda Hamilton원래의
2024-12-03 02:15:10727검색

How to Unmarshal Unknown Protobuf Messages in Go?

Go에서 알 수 없는 Protobuf 메시지 언마샬링

유형 캐스팅을 용이하게 하기 위해 protobuf 메시지를 인터페이스로 언마샬링하는 것은{} proto.Unmarshal 함수가 유형의 인수를 기대하기 때문에 가능하지 않습니다. proto.Message, 구체적인 protobuf 유형을 지정하는 인터페이스 구현.

알려진 메타데이터를 사용한 대체 접근 방식

최소한 일부 상황별 정보(예: 문자열 또는 숫자)가 바이트 슬라이스와 함께 제공되는 경우 해당 정보를 사용하여 예상되는 메타데이터에 매핑할 수 있습니다. protobuf 유형을 지정하고 전달하기 전에 인스턴스화합니다. proto.Unmarshal:

func decodeWithMetadata(data []byte, identifier string) error {
    var message proto.Message
    switch identifier {
        case "foo":
            message = &mypb.Foo{}
        case "bar":
            message = &mypb.Bar{}
    }
    if err := proto.Unmarshal(data, message); err != nil {
        return err
    }
    log.Printf("%v\n", data)
    return nil
}

완전히 알 수 없는 페이로드 구문 분석

그러나 바이트 페이로드를 전혀 알 수 없는 경우 와이어 형식의 protobuf 메시지에서 제한된 정보를 추출할 수 있는 protowire 패키지를 고려하세요. protobuf 메시지의 와이어 표현은 모호하여 의미 체계가 약하다는 점에 유의하세요.

파서 구현

다음 코드는 알 수 없는 protobuf 메시지를 구문 분석합니다.

type Field struct {
    Tag Tag
    Val Val
}

type Tag struct {
    Num int32
    Type protowire.Type
}

type Val struct {
    Payload interface{}
    Length int
}

func parseUnknown(b []byte) []Field {
    // ... implementation to parse unknown protobuf messages as described in the provided answer ...
}

샘플 사용법

protobuf 스키마 제공 like:

message Foo {
  string a = 1;
  string b = 2;
  Bar bar = 3;
}

message Bar {
  string c = 1;
}

다음 코드는 파서를 사용하는 방법을 보여줍니다.

// Parse the protobuf message as byte slice
b := []byte{0x0a, 0x01, 0x41, 0x12, 0x01, 0x42, 0x1a, 0x03, 0x43}
fields := parseUnknown(b)
for _, field := range fields {
    fmt.Printf("%#v\n", field)
}

출력:

main.Field{Tag:main.Tag{Num:1, Type:2}, Val:main.Val{Payload:[]uint8{0x41}, Length:1}}
main.Field{Tag:main.Tag{Num:2, Type:2}, Val:main.Val{Payload:[]uint8{0x42}, Length:1}}
main.Field{Tag:main.Tag{Num:1, Type:2}, Val:main.Val{Payload:[]uint8{0x43}, Length:1}}
main.Field{Tag:main.Tag{Num:3, Type:2}, Val:main.Val{Payload:[]main.Field{main.Field{Tag:main.Tag{Num:1, Type:2}, Val:main.Val{Payload:[]uint8{0x43}, Length:1}}}, Length:3}}

위 내용은 Go에서 알 수 없는 Protobuf 메시지를 어떻게 언마샬링하나요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.