繁体   English   中英

Protobuf 任何解组

[英]Protobuf Any unmarshal

我有一个使用 Any 类型的原型 API

message Document {
    DocumentMeta meta = 1;
    bytes data = 2;
    google.protobuf.Any details = 3;
}

在客户端,我创建了一条名为 Dog 的消息,并创建了详细信息字段,如下所示:

dog1 := events2.Dog{
    Name: "Leo",
    Id:   1,
}
var dst anypb.Any
err = anypb.MarshalFrom(&dst, &dog1, proto.MarshalOptions{})

包含 Dog proto 的 .pb 文件也被复制到服务器中。

如果我在服务器中打印文档,它会提供正确的信息

Any:type_url:"type.googleapis.com/com.test.eventbus.pb.events.Dog" value:"\n\x03Leo\x10\x01"

在服务器端,我在不提供特定 proto.Message 类型(Dog)的情况下解组

basicDog, err := anypb.UnmarshalNew(doc.GetDetails(), proto.UnmarshalOptions{})

UnmarshalNew 因proto: not found而失败

  1. 我在解组期间没有提供特定类型,因为允许客户端发送在应用程序启动期间可能未定义的任何类型的消息。
  2. 所以客户端生成一个新的 proto 文件,为 go 生成.pb 并将这个.go 文件复制到服务器内部。

如何在使用 unmarshalAny() 方法时在服务器端使用 .pb 文件?

尝试使用google.protobuf.Value

原型文件:

syntax = "proto3";

package mediation.common;

option go_package = ".;common";

import "google/protobuf/value.proto";

message Model {
  google.protobuf.Value any = 2;
}

使用:

package common

import (
    "encoding/json"
    "testing"

    "google.golang.org/protobuf/types/known/structpb"
)

type Dog struct {
    Id   int
    Name string
}

func TestAny(t *testing.T) {
    data := map[string]interface{}{
        "id":   1,
        "name": "kitty",
    }

    s, _ := structpb.NewValue(data)
    newData := s.GetStructValue()

    m := Model{Any: structpb.NewStructValue(newData)}

    var dog Dog
    unmarshal(m.GetAny(), &dog)
    t.Log(dog)

    var mm map[string]interface{}
    unmarshal(m.GetAny(), &mm)
    t.Log(mm)
}

func unmarshal(p *structpb.Value, o interface{}) error {
    byt, _ := p.MarshalJSON()
    return json.Unmarshal(byt, o)
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM