簡體   English   中英

在不知道它是什么類型的情況下解組原始編碼的消息

[英]Unmarshaling a proto encoded message without knowing what type it is

我想在不知道它是什么類型的情況下將[]byte放入 proto.Message 中。

為了添加更多細節,我知道編碼類型/消息可以是類型的集合 S。 (它們都是在我自己的 proto 文件中聲明的類型,並內置在 Go 二進制文件中。)

我想看看是否有可能獲取一個字節數組並從中重建原始消息。

我已經編寫了這個演示: https://play.golang.org/p/WF9KpTlZnp7如果我將描述符傳遞給它,我可以將它解碼為動態 pb,並從 Any 中返回一條消息。

Protocol Buffers 有線格式不是自描述的。 這意味着有關協議緩沖區類型的信息不使用消息本身進行編碼。 這就是為什么在解組期間必須提供類型。

在線上,protobuf 格式非常簡單。 基本上只有字段編號(注意不是名稱,只有數字)和值(序列化為字節)被編碼。

動態解碼消息有兩種策略。

一種是使用Any

https://github.com/protocolbuffers/protobuf/blob/master/src/google/protobuf/any.proto

對於能夠使用任何 package 解碼的消息,必須首先使用任何 package 對其進行編碼,並且必須在解碼和編碼原型注冊表中注冊類型。 這是因為,any 是通過簡單地對底層消息進行編碼,然后將其放入帶有引用該類型的字符串的消息中來實現的。 通常這被稱為信封,因為就像一封信一樣,原始消息是用這個額外的上下文(消息的類型)包裝的。

如果您可以同時控制編碼和解碼代碼,則此策略效果最佳。 如果可能的話,這將是推薦的策略。

另一種策略是使用dynamicpb並嘗試解析未知字段。 這是因為從 proto 3.5 開始,添加了未知字段。 如果原始消息被反序列化但原始類型不知道該字段,則剩余字段被推入未知字段。 消息類型中不傳遞類型信息和字段名稱。 因此,這些字段將顯示為具有未知名稱和類型的未知字段。

如果您的消息不同,但是,例如,共享一個具有相同編號和類型的字段來描述該類型,這可以用於首先反序列化該字段,然后在打開第一個已知信息后反序列化其余字段場地。

對於不控制編碼路徑且不是推薦策略的系統,這更像是一種解決方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM