Heim >Backend-Entwicklung >Golang >Wie gehe ich mit dem Unmarshaling unbekannter Protobuf-Nachrichten um?

Wie gehe ich mit dem Unmarshaling unbekannter Protobuf-Nachrichten um?

DDD
DDDOriginal
2024-12-02 16:51:16209Durchsuche

How to Handle Unmarshaling of Unknown Protobuf Messages?

Protobuf Unmarshal: Umgang mit unbekannten Nachrichten

In Szenarien, in denen der Nachrichtentyp in einer Protobuf-Nutzlast nicht im Voraus bekannt ist, erfolgt das Unmarshaling in eine Schnittstelle Der Typ {} ist nicht möglich, da er eine Implementierung der Protobuf-Nachricht erfordert Schnittstelle.

Alternativer Ansatz

Wenn zumindest Teilinformationen zur Protobuf-Nutzlast verfügbar sind, z. B. eine Zeichenfolge oder eine Zahl, können Sie diese als Schlüssel zur Instanziierung verwenden den entsprechenden konkreten Protobuf-Typ und führen Sie dann das Unmarshaling durch.

Handhabung wirklich unbekannt Nachrichten

Wenn alle Informationen zum Nachrichtentyp fehlen, kann das Protowire-Paket verwendet werden, um begrenzte Informationen aus dem Wire-Format der Protobuf-Nutzlast zu extrahieren.

Risiken und Einschränkungen

Das Parsen unbekannter Proto-Nachrichten stellt bestimmte Probleme dar Herausforderungen:

  • Mehrdeutige Darstellung:Das Drahtformat kann mehrdeutig sein, was es schwierig macht, den genauen Typ bestimmter Datenstrukturen zu bestimmen.
  • Verlust Anzahl der Unterfeldinformationen: Bei verpackten Nachrichten kann der Kontext zum Kabeltyp und der Tag-Nummer verloren gehen, was möglicherweise die Rekonstruktion der Originalnachricht einschränkt Struktur.
  • Ausschluss von Nicht-Proto-Typen: Nicht-Proto-Daten wie verpacktes JSON oder XML werden möglicherweise nicht genau erfasst.

Beispiel Implementierung

Der folgende Code bietet ein Beispiel für das Parsen eines unbekannten Protobufs Nachricht:

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
}

Fazit

Das Parsen wirklich unbekannter Protobuf-Nachrichten ist eine komplexe Aufgabe, aber durch die Nutzung des Protowire-Pakets können Sie begrenzte Informationen extrahieren, die möglicherweise ausreichend sind für Ihr spezifisches Szenario. Denken Sie daran, dass dieser Ansatz nicht für Anwendungen in Produktionsqualität geeignet ist, bei denen eine genaue Darstellung von entscheidender Bedeutung ist.

Das obige ist der detaillierte Inhalt vonWie gehe ich mit dem Unmarshaling unbekannter Protobuf-Nachrichten um?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
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