为了账号安全,请及时绑定邮箱和手机立即绑定

任何带有 grpc 的字段总是为零

任何带有 grpc 的字段总是为零

Go
素胚勾勒不出你 2022-09-12 20:30:00
我正在将gRPC与戈朗一起使用。我有一个非常简单的原型定义和一个gRPC服务。原始定义在谷歌/原型布夫/任何类型的认可中有一个字段。gRPC 服务无法将此字段映射到输入值,并且始终初始化为零原型定义:syntax = "proto3";option go_package = "service";option java_multiple_files = true;option java_package = "io.grpc.consensus";import "google/protobuf/any.proto";package service;service MyService {  rpc Verify (Payload) returns (Response) {}}message Response {  string policyId =1;  string txnId =2;}message Endorsement {  string endorserId=1;  // This is being initialise to nil by gRPC  google.protobuf.Any data = 2;  string signature=3;  bool isVerified=4;}message Payload {  string policyId =1;  string txnId =2;  repeated Endorsement endorsements=3;}使用这个,一个简单的gRPC服务被实现:package serviceimport (    "log"    "golang.org/x/net/context")type ServiceServerImpl struct {}func NewServiceServerImpl() *ServiceServerImpl {    return &ServiceServerImpl{}}func (s *ServiceServerImpl) Verify(ctx context.Context, txnPayload *Payload) (*Response, error) {    log.Printf("Got verification request: %s", txnPayload.TxnId)    for _, endorsement := range txnPayload.Endorsements {        j, err := endorsement.Data.UnmarshalNew()        if err != nil {            log.Print("Error while unmarshaling the endorsement")        }        if j==nil {       //This gets printed as payload's endorsement data is always null for google/protobuf/any type            log.Print("Data is null for endorsement")        }    }    return &Response{TxnId: txnPayload.TxnId,  PolicyId: txnPayload.PolicyId}, nil}输入数据:{  "policyId": "9dd97b1e-b76f-4c49-b067-22143c954e75",  "txnId": "231-4dc0-8e54-58231df6f0ce",  "endorsements": [    {      "endorserId": "67e1dfbd-1716-4d91-94ec-83dde64e4b80",      "data": {        "type": "issueTx",        "userId": 1,        "transaction": {            "amount": 10123.50        }    },      "signature": "MEUCIBkooxG2uFZeSEeaf5Xh5hWLxcKGMxCZzfnPshOh22y2AiEAwVLAaGhccUv8UhgC291qNWtxrGawX2pPsI7UUA/7QLM=",      "isVerified": false    }  ]}
查看完整描述

2 回答

?
月关宝盒

TA贡献1772条经验 获得超5个赞

如您所知,是消息类型,因此当您没有为其设置任何值时,它将为零。google.protobuf.Any


您必须使用您的结构取消封送数据,请参阅下面来自 protobuf 示例的代码


      // marshal any

      foo := &pb.Foo{...}

      any, err := anypb.New(foo)

      if err != nil {

        ...

      }

      // unmarshal any 

      foo := &pb.Foo{}

      if err := any.UnmarshalTo(foo); err != nil {

        ...

      }


或者我认为你可以用它与指针接口(&接口{})一起使用,如下所示:


      d := &interface{}{}

      if err := endorsement.Data.UnmarshalTo(d); err != nil {

        ...

      }


查看完整回答
反对 回复 2022-09-12
?
qq_笑_17

TA贡献1818条经验 获得超7个赞

从软件包1 文档取消编组任何

UnmarshalNew使用全局类型注册表解析消息类型,并构造该消息的新实例以取消编组。为了使消息类型显示在全局注册表中,必须将表示该 protobuf 消息类型的 Go 类型链接到 Go 二进制文件中。对于由原始生成生成的消息,这是通过导入表示 .proto 文件的生成的 Go 包来实现的

注册表的类型为 。类型查找是使用字段完成的,该字段在封送原始消息时由 gRPC 客户端设置为具体类型的 url。protoregistry.GlobalTypesAny.TypeUrl

令人困惑的细节是,它可以是任何原始缓冲区消息,但该原始缓冲区消息必须在某个地方定义Any

您的文件没有与输入中的对象匹配的消息定义。可能是此消息在其他地方定义(不在您自己的原型文件中),但无论如何,您都必须导入生成的消息所在的Go包。.protodataData

否则,如果输入不是来自已定义的原型消息,您可以自己向原型添加消息定义,然后使用 UnmarshalTo

// proto file

message Data {

    string type = 1;

    int user_id = 2;

    Transaction transaction = 3;

}


message Transaction {

    float amount = 1;

}

然后:


    for _, endorsement := range txnPayload.Endorsements {

        data := generated.Data{}

        err := endorsement.Data.UnmarshalTo(&data)

        if err != nil {

            log.Print("Error while unmarshaling the endorsement")

        }

    }

如果您只需要任意的字节序列,即真正未知的类型,请使用原型类型并将其视为 JSON 有效负载。bytes


将其建模为 Go 结构:


type Data struct {

    Type     string `json:"type"`

    UserID   int    `json:"userId"`

    Transaction struct{

        Amount float64 `json:"amount"`

    } `json:"transaction"`


}

或者,如果客户可以发送任何东西。map[string]interface{}


然后在您的处理程序功能中:


    for _, endorsement := range txnPayload.Endorsements {

        data := Data{} // or `map[string]interface{}`

        err := json.Unmarshal(endorsement.Data, &data)

        if err != nil {

            log.Print("Error while unmarshaling the endorsement")

        }

    }


查看完整回答
反对 回复 2022-09-12
  • 2 回答
  • 0 关注
  • 152 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信