Golang中使用grpc.Dial建立连接后,客户端如何发送gRPC元数据?
嘿,我来帮你搞定这个问题!在Go的gRPC客户端里,要发送元数据(也就是你说的自定义请求头),核心是用官方的google.golang.org/grpc/metadata包,下面我给你两种常用的实现方式,按需选就行:
方法一:给所有请求设置全局元数据
如果你需要让通过这个连接发送的每一个请求都带上相同的元数据(比如全局的认证token、客户端标识),可以在调用grpc.Dial的时候,通过grpc.WithPerRPCCredentials选项来配置。
你需要实现credentials.PerRPCCredentials接口的两个方法:GetRequestMetadata和RequireTransportSecurity。举个例子:
import ( "context" "google.golang.org/grpc/credentials" "google.golang.org/grpc/metadata" ) // 自定义凭证结构体,用来存要发送的元数据 type customCredentials struct { token string appID string } func (c customCredentials) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) { // 返回要发送的元数据,key建议用小写(HTTP/2头字段是小写的) return map[string]string{ "x-auth-token": c.token, "x-app-id": c.appID, }, nil } func (c customCredentials) RequireTransportSecurity() bool { // 如果你的gRPC连接是用TLS加密的,返回true;否则返回false return false } // 然后在Dial的时候用这个选项 conn, err := grpc.Dial(serverAddr, grpc.WithPerRPCCredentials(customCredentials{ token: "your-auth-token", appID: "client-app-001", })) if err != nil { // 处理错误 }
这样之后,所有通过这个conn发送的gRPC请求,都会自动带上你定义的元数据。
方法二:给单个请求设置元数据
如果只是想给某一个特定请求添加自定义元数据,那更灵活的方式是把元数据附加到请求的context里,再传给gRPC方法。
示例代码如下:
import ( "context" "google.golang.org/grpc/metadata" ) // 1. 创建元数据对象 md := metadata.Pairs( "x-request-id", "req-12345", "x-user-agent", "grpc-go-client/v1.0", ) // 2. 把元数据附加到context中 ctx := metadata.NewOutgoingContext(context.Background(), md) // 3. 调用gRPC方法时传入这个context resp, err := yourGRPCClient.YourMethod(ctx, &yourRequest) if err != nil { // 处理错误 }
这种方式只会影响这个特定的请求,其他请求不受影响。
额外注意点
- 元数据的key建议使用小写字母,因为gRPC底层基于HTTP/2,而HTTP/2的头字段名称是强制小写的,大写key会被自动转成小写。
- 如果同时用了全局元数据和单个请求的元数据,两者会合并:相同key的情况下,单个请求的元数据值会和全局值并存(服务器会收到该key的多个值),如果需要覆盖可以单独处理。
- 如果你需要发送二进制数据作为元数据,可以用
metadata.New方法传入map[string][]string,其中值需要是经过Base64编码的字符串(因为HTTP/2头字段只能是ASCII格式)。
内容的提问来源于stack exchange,提问作者bharat nc
相关产品推荐
相关产品推荐

