Heim > Backend-Entwicklung > Golang > Wie entmarshaliere ich unbekannte Protobuf-Nachrichten in Go?

Wie entmarshaliere ich unbekannte Protobuf-Nachrichten in Go?

Linda Hamilton
Freigeben: 2024-12-03 02:15:10
Original
728 Leute haben es durchsucht

How to Unmarshal Unknown Protobuf Messages in Go?

Unmarshalling unbekannter Protobuf-Nachrichten in Go

Unmarshalling von Protobuf-Nachrichten in einer Schnittstelle{} zur Erleichterung der Typumwandlung ist nicht möglich, da die Funktion proto.Unmarshal ein Argument vom Typ erwartet proto.Message, eine Schnittstelle, die konkrete Protobuf-Typen implementieren.

Alternativer Ansatz mit bekannten Metadaten

In Fällen, in denen dem Byte-Slice zumindest einige Kontextinformationen (z. B. eine Zeichenfolge oder eine Zahl) beiliegen, können Sie diese Informationen verwenden, um sie dem erwarteten Protobuf-Typ zuzuordnen und ihn zu instanziieren, bevor Sie ihn an Proto übergeben .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
}
Nach dem Login kopieren

Völlig unbekannte Nutzlasten analysieren

Allerdings, wenn Die Byte-Nutzlast ist völlig unbekannt. Betrachten Sie das Protowire-Paket, das das Extrahieren begrenzter Informationen aus Wire-formatierten Protobuf-Nachrichten ermöglicht. Beachten Sie, dass die Drahtdarstellung von Protobuf-Nachrichten mehrdeutig ist, was zu einer schwachen Semantik führt.

Parser-Implementierung

Der folgende Code analysiert unbekannte Protobuf-Nachrichten:

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 ...
}
Nach dem Login kopieren

Beispiel Verwendung

Angesichts eines Protobuf-Schemas wie:

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

message Bar {
  string c = 1;
}
Nach dem Login kopieren

Der folgende Code zeigt, wie der Parser verwendet wird:

// 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)
}
Nach dem Login kopieren

Ausgabe:

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}}
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonWie entmarshaliere ich unbekannte Protobuf-Nachrichten in Go?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage