将 gRPC 拦截器中的请求转换为相关的 protobuf 消息
Cast request in gRPC interceptor to relevant protobuf message
我有一个 UnaryServerInterceptor
接收 req
Interface{}
。此 req
可以是我的任何一条消息,但在这种情况下,我的所有消息都有一个共同的 metadata
子消息。
Protobuf 定义(示例)
message ClientMeta {
string info = 1;
}
message PingRequest {
ClientMeta metadata = 1;
}
message OtherRequest {
ClientMeta metadata = 1;
}
service Blah {
rpc Ping (PingRequest) returns (PingResponse) {}
rpc Other (OtherRequest) returns (OtherResponses) {}
}
拦截器
func (i *authInterceptor) unary() grpc.UnaryServerInterceptor {
return func(
ctx context.Context,
req interface{},
info *grpc.UnaryServerInfo,
handler grpc.UnaryHandler,
) (interface{}, error) {
log.Info().Msgf("interceptor: %s", info.FullMethod)
}
}
我需要在我的拦截器中访问消息 metadata
的属性。问题是我不知道它是哪条消息,所以我不能直接投射它。我有几条不同的消息,但它们都有 metadata
的共同点。
解决此问题的最佳方法是什么?
protoc
一代应该为这两种类型产生了一种名为 GetMetadata
的方法。您可以使用 类型断言 检查传入消息是否实现了接口(有关详细信息,请参阅 tour of go),然后调用该方法来获取元数据。
type HasMetadata interface {
GetMetadata() *ClientMeta
}
在处理消息的函数中,做这样的事情
if m, ok := req.(HasMetadata); ok {
return m.GetMetadata()
}
我有一个 UnaryServerInterceptor
接收 req
Interface{}
。此 req
可以是我的任何一条消息,但在这种情况下,我的所有消息都有一个共同的 metadata
子消息。
Protobuf 定义(示例)
message ClientMeta {
string info = 1;
}
message PingRequest {
ClientMeta metadata = 1;
}
message OtherRequest {
ClientMeta metadata = 1;
}
service Blah {
rpc Ping (PingRequest) returns (PingResponse) {}
rpc Other (OtherRequest) returns (OtherResponses) {}
}
拦截器
func (i *authInterceptor) unary() grpc.UnaryServerInterceptor {
return func(
ctx context.Context,
req interface{},
info *grpc.UnaryServerInfo,
handler grpc.UnaryHandler,
) (interface{}, error) {
log.Info().Msgf("interceptor: %s", info.FullMethod)
}
}
我需要在我的拦截器中访问消息 metadata
的属性。问题是我不知道它是哪条消息,所以我不能直接投射它。我有几条不同的消息,但它们都有 metadata
的共同点。
解决此问题的最佳方法是什么?
protoc
一代应该为这两种类型产生了一种名为 GetMetadata
的方法。您可以使用 类型断言 检查传入消息是否实现了接口(有关详细信息,请参阅 tour of go),然后调用该方法来获取元数据。
type HasMetadata interface {
GetMetadata() *ClientMeta
}
在处理消息的函数中,做这样的事情
if m, ok := req.(HasMetadata); ok {
return m.GetMetadata()
}