You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将二进制gRPC元数据反序列化为Rust结构体?

问题:gRPC二进制元数据反序列化为Rust结构体失败

尝试将客户端传来的二进制gRPC元数据反序列化为Rust结构体,按建议使用bincode处理后反序列化,但运行时触发错误。

结构体定义

#[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();

错误信息

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

二进制数据示例

x-auth-metadata-bin: CiA4NGIxOTE5NTUxZWM1ZGE5M2M1MzI4MzY5ODc5ZjNjMhIHYW5kcm9pZCD0oLADKgZtYXN0ZXIyJVhVMEQwNTgwQTgwQzgyMjc2RDlERjMzQjREMjA2NjVDNDJFMzM6B2FuZHJvaWQ

解决方案

问题根源

  1. 客户端传来的元数据是Base64编码的Protobuf二进制数据,而非bincode格式,用bincode反序列化必然失败。
  2. gRPC的二进制元数据字段默认会做Base64编码传输,需要先解码得到原始Protobuf二进制。

修改后的代码

首先确保依赖中包含base64 crate:

# Cargo.toml
[dependencies]
prost = "0.12"
base64 = "0.21"

处理逻辑调整为:

use base64::engine::{general_purpose, Engine as _};

// 获取Base64编码的元数据
let req_metadata_base64 = request.metadata().get_bin("x-auth-metadata-bin").unwrap().as_ref();
// 解码Base64得到原始Protobuf二进制
let req_metadata_bin = general_purpose::STANDARD.decode(req_metadata_base64).unwrap();
// 使用prost的Message::decode方法反序列化
let req_metadata = Metadata::decode(&*req_metadata_bin).unwrap();

额外优化

如果不需要同时支持serde序列化,可以去掉结构体上的serde::Serialize和serde::Deserialize derive,减少不必要的依赖:

#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Metadata {
    // ... 字段定义不变
}

内容的提问来源于stack exchange,提问作者cxw620

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 09:16:13