gRPC GO 中的动态定义消息
Dynamic defined message in gRPC GO
我是 Go 中 gRPC 的新用户。
我已经完成了有关客户端流的代码 API。现在我有一个问题。
据我所知,我们必须在proto文件中定义message struct,然后protoc基于这个定义的message struct来生成代码。在我的例子中,protoc 生成 Go 代码。但是这个过程限制了客户端或服务器的重用API。例如,对于 client-streaming 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
}
好像有点不方便
那么,客户端如何在 gRPC 中使用动态消息结构?
如果是,请给我一个客户端流的例子API。
我不确定我是否正确理解了你的问题,但我假设我理解了。 Protobuf 是一种定义两个服务之间的通信协议的方法,而不限制那些服务器的底层技术。
protoc
生成的代码仅用于服务间通信。如果你想在它们上面有额外的方法和存根代码,你需要在两端都有包装器结构。因为这是使用 protobuf
的惯用方式
例如
type MyStruct{
pb.Mystruct
}
func (m MyStruct) CalculateWeather() (int,error){
...
}
通常情况下,您应该为每种情况定义不同的结构。我不确定你想要什么,但你可以简单地编组你的对象并发送字节,然后解组回来
使用Any
消息类型:
syntax = "proto3";
import "google/protobuf/any.proto";
message Example {
string id = 1;
google.protobuf.Any message = 2;
}
使用Any
,您可以使用任何用户定义的原型消息,还需要使用一些常见的存储库或注册表与客户端共享新的原型消息。
听起来你要的是:
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
}
请记住,DataRequest
和 DataResponse
是可扩展的,因此您可以在将来根据需要向它们添加字段。
我是 Go 中 gRPC 的新用户。
我已经完成了有关客户端流的代码 API。现在我有一个问题。
据我所知,我们必须在proto文件中定义message struct,然后protoc基于这个定义的message struct来生成代码。在我的例子中,protoc 生成 Go 代码。但是这个过程限制了客户端或服务器的重用API。例如,对于 client-streaming 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
}
好像有点不方便
那么,客户端如何在 gRPC 中使用动态消息结构?
如果是,请给我一个客户端流的例子API。
我不确定我是否正确理解了你的问题,但我假设我理解了。 Protobuf 是一种定义两个服务之间的通信协议的方法,而不限制那些服务器的底层技术。
protoc
生成的代码仅用于服务间通信。如果你想在它们上面有额外的方法和存根代码,你需要在两端都有包装器结构。因为这是使用 protobuf
例如
type MyStruct{
pb.Mystruct
}
func (m MyStruct) CalculateWeather() (int,error){
...
}
通常情况下,您应该为每种情况定义不同的结构。我不确定你想要什么,但你可以简单地编组你的对象并发送字节,然后解组回来
使用Any
消息类型:
syntax = "proto3";
import "google/protobuf/any.proto";
message Example {
string id = 1;
google.protobuf.Any message = 2;
}
使用Any
,您可以使用任何用户定义的原型消息,还需要使用一些常见的存储库或注册表与客户端共享新的原型消息。
听起来你要的是:
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
}
请记住,DataRequest
和 DataResponse
是可扩展的,因此您可以在将来根据需要向它们添加字段。