首頁  >  文章  >  後端開發  >  如何在 Go 中解組未知協定緩衝區?

如何在 Go 中解組未知協定緩衝區?

Susan Sarandon
Susan Sarandon原創
2024-11-23 08:45:15726瀏覽

How to Unmarshal Unknown Protocol Buffers in Go?

在Go 中解組未知協定緩衝區

使用協定緩衝區(protobuf) 時,可能會遇到收到訊息類型的情況未知。當偵聽來自多個來源的訊息或處理動態或不可預測的訊息類型時,可能會發生這種情況。

Protobuf 的預設 Unmarshal 函數需要將特定的訊息類型作為參數傳遞,但這在訊息時不可行類型未知。常見的方法是嘗試解組到介面{}中,但 Protobuf 庫不支援這種方式。

解決限制

要處理未知訊息,有必要實作自訂方法。一種解決方案是使用 protowire 包,它提供對 protobuf 訊息的線路表示的低階存取。

解析未知訊息

以下程式碼片段示範如何從未知的protobuf 訊息中解析並擷取訊息:

type Field struct {
    Tag
    Val
}

type Tag struct {
    Num int32
    Type protowire.Type
}

type Val struct {
    Payload interface{}
    Length int
}

func parseUnknown(b []byte) []Field {
    // ...
}

parseUnknown 迭代函數位元組數組,使用字段並提取有關每個字段的標籤和值的基本資訊。

提取有效負載

提取的值有效負載可以儲存在各種資料結構中,取決於欄位的預期類型和內容。例如:

switch t {
case protowire.VarintType:
    v, vlen := protowire.ConsumeVarint(b[taglen:fieldlen])
case protowire.Fixed64Type:
    v, vlen := protowire.ConsumeFixed64(b[taglen:fieldlen])
// ...
}

限制和注意事項

這種方法有一定的限制:

  • 歧義: protobuf 訊息的線路表示可能不明確,因此很難確定值的確切類型在某些情況下。
  • 未知欄位:任何未知或不支援的欄位類型都不會被解析或保留。
  • 子訊息:子-訊息被遞歸解析,但類型資訊是遺失。
  • 重複欄位: 未明確處理重複欄位。

解析未知訊息的替代方法

在大多數情況下,最好從不同的角度來處理未知訊息的問題,例如下:

  • 映射到通用訊息:建立一個通用訊息類型,可以封裝所有可能的字段,並將未知訊息映射到此通用類型。
  • 使用Any Proto: 考慮使用Any proto 類型來封裝未知訊息並保留類型資訊以供以後使用

本文描述的方法提供了一種從未知的protobuf 訊息中提取基本資訊的方法,但當其他選項不可行時,應將其用作後備解決方案。

以上是如何在 Go 中解組未知協定緩衝區?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn