gRPC GO 中动态定义的消息

问题描述

我是 Go 中 gRPC 的新用户

我已经完成了关于客户端流 API 的代码。现在我有一个问题。

据我所知,我们必须在 proto 文件中定义 message struct,然后 protoc 基于这个定义的 message struct 来生成代码。就我而言,protoc 生成 Go 代码。但是这个过程限制了客户端或者服务器重用API。例如,对于客户端流 API,首先,客户端使用此 API 将温度数据发送到服务器。如果客户端想将 GPS 坐标发送到服务器,则客户端必须重新定义消息结构,因为温度的构造与 GPS 坐标的构造不同。但同样的目的是将数据发送到服务器。

Syntax = "proto3";
package calculator;
option go_package="calculatorpb";
message TemperatureRequest{
     float num =1;
}
message TemperatureResponse{
     float result =1;
}
message CoordinatesRequest{
     float long =1;
     float lat =1;
}
message CoordinatesResponse{
     float result =1;
}
service  CalculatorService{
   rpc Temperature(stream AverageRequest) returns (AverageResponse){} //client streaming for temperature    
   rpc Coordinates(stream CoordinatesRequest) returns (CoordinatesResponse){} //client streaming  for  Coordinates
}

好像不方便。

那么,客户端如何在 go 中使用带有 gRPC 的动态消息结构?

如果是,请给我一个客户端流 API 的示例。

解决方法

使用 Any 消息类型:

syntax = "proto3";

import "google/protobuf/any.proto";

message Example {
    string id = 1;
    google.protobuf.Any message = 2;
}

使用 Any,您可以使用任何用户定义的 proto 消息,您还需要使用一些常见的 repo 或注册表与客户端共享新的 proto 消息。

,

我不确定我是否正确理解了您的问题,但我假设我理解了。 Protobuf 是一种定义两个服务之间通信协议的方式,而不限制那些服务器的底层技术。

protoc 生成的代码仅用于服务之间的通信。如果你想有额外的方法和存根代码,你需要两端的包装结构。因为这是使用protobuf的惯用方式

例如

type MyStruct{

pb.Mystruct

}

func (m MyStruct) CalculateWeather() (int,error){

...

}


通常,您应该为每种情况定义不同的结构。我不确定你想要什么,但你可以简单地编组你的对象并发送字节,然后解组

,

听起来您要的是:

syntax = "proto3";
package calculator;
option go_package="calculatorpb";

// message TemperatureRequest,TemperatureResponse,CoordinatesRequest,CoordinatesResponse defined as in your example

message DataRequest {
  TemperatureRequest temperature_request = 1;
  CoordinatesRequest coordinates_request = 2;
}
message DataResponse {
  TemperatureResponse temperature_response = 1;
  CoordinatesResponse coordinates_response = 2;
}

service  CalculatorService{
   rpc Data(stream DataRequest) returns (DataResponse){} //client streaming for data
}

请记住,DataRequestDataResponse 是可扩展的,因此您可以在将来根据需要向其中添加字段。