ホームページ >バックエンド開発 >Golang >不明な Protobuf メッセージのアンマーシャリングを処理するにはどうすればよいですか?

不明な Protobuf メッセージのアンマーシャリングを処理するにはどうすればよいですか?

DDD
DDDオリジナル
2024-12-02 16:51:16210ブラウズ

How to Handle Unmarshaling of Unknown Protobuf Messages?

Protobuf Unmarshal: 不明なメッセージの処理

protobuf ペイロード内のメッセージ タイプが事前に不明なシナリオでは、インターフェイスへのアンマーシャリングが行われます。 {} タイプは、protobuf メッセージの実装が必要なため実現できません。

代替アプローチ

文字列や数値など、protobuf ペイロードに付随する少なくとも部分的な情報が利用可能な場合、これをインスタンス化するためのキーとして使用できます。適切な具体的な protobuf タイプを指定してから、アンマーシャリングを実行します。

本当に不明な処理メッセージ

メッセージ タイプに関するすべての情報が存在しない場合、protowire パッケージを利用して protobuf ペイロードのワイヤ形式から限られた情報を抽出できます。

リスクと制限

不明なプロト メッセージを解析すると、特定のメッセージが表示されます課題:

  • あいまいな表現: ワイヤ形式があいまいな場合があるため、特定のデータ構造の正確なタイプを判断することが困難になります。
  • 損失サブフィールド情報の: ラップされたメッセージはワイヤ タイプとタグ番号に関するコンテキストを失う可能性があり、元のメッセージを再構築する機能が制限される可能性があります。構造体。
  • 非プロトタイプの除外: ラップされた JSON や XML などの非プロトデータは正確にキャプチャされない可能性があります。

サンプル実装

以下のコードは、未知のオブジェクトを解析する例を示しています。 protobuf メッセージ:

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 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。