簡體   English   中英

如何將二進制 gRPC 元數據反序列化為 Rust 結構?

[英]How to deserialize binary gRPC metadata to Rust struct?

這是我的代碼。

#[derive(serde::Serialize, serde::Deserialize)]
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Metadata {
    /// login token
    #[prost(string, tag = "1")]
    pub access_key: ::prost::alloc::string::String,
    /// pack type
    #[prost(string, tag = "2")]
    pub mobi_app: ::prost::alloc::string::String,
    /// device
    #[prost(string, tag = "3")]
    pub device: ::prost::alloc::string::String,
    /// inner build id
    #[prost(int32, tag = "4")]
    pub build: i32,
    /// channel
    #[prost(string, tag = "5")]
    pub channel: ::prost::alloc::string::String,
    /// device buvid
    #[prost(string, tag = "6")]
    pub buvid: ::prost::alloc::string::String,
    /// app platform
    #[prost(string, tag = "7")]
    pub platform: ::prost::alloc::string::String,
}
//...
let req_metadata_bin = request
            .metadata()
            .get_bin("x-auth-metadata-bin")
            .unwrap()
            .as_ref();
let req_metadata: Metadata = bincode::deserialize(req_metadata_bin).unwrap();

我正在嘗試反序列化來自客戶端的二進制 gRPC 元數據。 有人告訴我通過 bincode 運行結果並將其反序列化為結構,但我不知道具體如何操作並編寫了上面的代碼,顯然它不起作用。

thread 'tokio-runtime-worker' panicked at 'called `Result::unwrap()` on an `Err` value: Io(Custom { kind: UnexpectedEof, error: "" })'

我用谷歌搜索解決方案,但一無所獲。 任何建議或代碼示例都會對我有很大幫助。

二進制數據示例:

x-auth-metadata-bin: CiA4NGIxOTE5NTUxZWM1ZGE5M2M1MzI4MzY5ODc5ZjNjMhIHYW5kcm9pZCD0oLADKgZtYXN0ZXIyJVhVMEQwNTgwQTgwQzgyMjc2RDlERjMzQjREMjA2NjVDNDJFMzM6B2FuZHJvaWQ

我假設以下是您最小的可重現示例

#[derive(serde::Serialize, serde::Deserialize)]
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Metadata {
    /// login token
    #[prost(string, tag = "1")]
    pub access_key: ::prost::alloc::string::String,
    /// pack type
    #[prost(string, tag = "2")]
    pub mobi_app: ::prost::alloc::string::String,
    /// device
    #[prost(string, tag = "3")]
    pub device: ::prost::alloc::string::String,
    /// inner build id
    #[prost(int32, tag = "4")]
    pub build: i32,
    /// channel
    #[prost(string, tag = "5")]
    pub channel: ::prost::alloc::string::String,
    /// device buvid
    #[prost(string, tag = "6")]
    pub buvid: ::prost::alloc::string::String,
    /// app platform
    #[prost(string, tag = "7")]
    pub platform: ::prost::alloc::string::String,
}

fn main() {
    let req_metadata_bin = base64::decode("CiA4NGIxOTE5NTUxZWM1ZGE5M2M1MzI4MzY5ODc5ZjNjMhIHYW5kcm9pZCD0oLADKgZtYXN0ZXIyJVhVMEQwNTgwQTgwQzgyMjc2RDlERjMzQjREMjA2NjVDNDJFMzM6B2FuZHJvaWQ=").unwrap();
    let req_metadata: Metadata = bincode::deserialize(&req_metadata_bin).unwrap();
    println!("{:#?}", req_metadata);
}
thread 'main' panicked at 'called `Result::unwrap()` on an `Err` value: Io(Custom { kind: UnexpectedEof, error: "" })', src/main.rs:30:74

bincode是一種與ProtoBuf完全不同的格式。 要解碼 protobuf 消息,您必須使用實際的 protobuf 解碼器。

像這樣:

#[derive(serde::Serialize, serde::Deserialize)]
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Metadata {
    /// login token
    #[prost(string, tag = "1")]
    pub access_key: ::prost::alloc::string::String,
    /// pack type
    #[prost(string, tag = "2")]
    pub mobi_app: ::prost::alloc::string::String,
    /// device
    #[prost(string, tag = "3")]
    pub device: ::prost::alloc::string::String,
    /// inner build id
    #[prost(int32, tag = "4")]
    pub build: i32,
    /// channel
    #[prost(string, tag = "5")]
    pub channel: ::prost::alloc::string::String,
    /// device buvid
    #[prost(string, tag = "6")]
    pub buvid: ::prost::alloc::string::String,
    /// app platform
    #[prost(string, tag = "7")]
    pub platform: ::prost::alloc::string::String,
}

fn main() {
    let req_metadata_bin = base64::decode("CiA4NGIxOTE5NTUxZWM1ZGE5M2M1MzI4MzY5ODc5ZjNjMhIHYW5kcm9pZCD0oLADKgZtYXN0ZXIyJVhVMEQwNTgwQTgwQzgyMjc2RDlERjMzQjREMjA2NjVDNDJFMzM6B2FuZHJvaWQ=").unwrap();
    let req_metadata: Metadata = prost::Message::decode(req_metadata_bin.as_slice()).unwrap();
    println!("{:#?}", req_metadata);
}
Metadata {
    access_key: "84b1919551ec5da93c5328369879f3c2",
    mobi_app: "android",
    device: "",
    build: 7082100,
    channel: "master",
    buvid: "XU0D0580A80C82276D9DF33B4D20665C42E33",
    platform: "android",
}

暫無
暫無

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

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