我正在使用gRPC和protobuf(以及使用REST的gRPC网关)构建一个客户端/服务器系统.
我在服务器端的上下文中使用元数据来承载来自客户端的身份验证数据,这非常有效.
现在,我希望服务器设置一些元数据键/值,以便客户端可以获得它们以及响应.我怎样才能做到这一点?使用SetHeader和SendHeader?理想情况下,我希望服务器的每一个响应都能集成那些元数据(可以看作某种UnaryInterceptor,但是响应而不是请求?)
我终于找到了自己的方式:https://github.com/grpc/grpc-go/blob/master/Documentation/grpc-metadata.md
所以基本上,grpc.SetHeader()+ grpc.SendHeader()并且grpc.SetTrailer()完全是我想要的.在客户端,grpc.Header()和grpc.Trailer()功能需要传递给RPC调用,他们的说法是一个metadata.MD被填充的对象.
在客户端,定义您的接收元数据:
var header, trailer metadata.MD
Run Code Online (Sandbox Code Playgroud)
然后,将它传递给SomeRPCCall()一元RPC:
response, err := client.SomeRPCCall(
context.Background(),
proto.MyMessage{},
grpc.Header(&header),
grpc.Trailer(&trailer),
)
Run Code Online (Sandbox Code Playgroud)
现在,您可以查看元数据中的内容:
for key, value := range header {
fmt.Printf("%s => %s", key, value)
}
for key, value := range trailer {
fmt.Printf("%s => %s", key, value)
}
Run Code Online (Sandbox Code Playgroud)
在服务器端,您可以:
强制在收到RPC之后(但在处理之前)发送数据:
grpc.SendHeader(ctx, metadata.New(map[string]string{"my-key": "my-value"}))
或者在RPC过程结束时设置和发送元数据(以及Status):
grpc.SetTrailer(ctx, metadata.New(map[string]string{"my-key": "my-value"}))