Protobuf Unmarshal:處理未知訊息
在預先未知protobuf 有效負載中的訊息類型的情況下,解組到介面中{ } 類型不可行,因為它需要protobuf 訊息的實作介面。
替代方法
當protobuf 負載附帶的至少部分資訊可用時,例如字串或數字,您可以使用它作為實例化的鍵適當的特定protobuf類型,然後執行解組。
處理真正的未知消息
如果不存在有關消息類型的所有信息,可以利用 protowire 包從 protobuf 有效負載的有線格式中提取有限的信息。
風險與限制
解析未知的原始訊息會出現某些問題挑戰:
示例實現
下面的代碼提供了解析未知protobuf的示例message:
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中文網其他相關文章!