dubbo-go
dubbo-go copied to clipboard
grpc Context failed to transfer attachment data
What happened: 当使用grpc的Context时, 无法将值从客户端传递到服务端
What you expected to happen:
How to reproduce it (as minimally and precisely as possible): [email protected]
syntax = "proto3";
option java_multiple_files = true;
option java_package = "demo.micro.server.proto";
option java_outer_classname = "sc";
option objc_class_prefix = "demo";
package proto;
option go_package = ".;demo";
// 编译命令 protoc -I ./ demo.proto --dubbo_out=plugins=grpc+dubbo:.
service SContext {
rpc FContext(Req) returns (Res){}
}
message Req{
string data = 1;
}
message Res{
string data = 1;
}
//客户端:
req := &demo.Req{}
res := &demo.Res{}
err := consumer.GetContextImpl().FContext(context.WithValue(context.Background(), constant.AttachmentKey, map[string]interface{}{
"socket.addr": "127.0.0.1:12788",
}), req, res)
//服务端:
func (g *Provider) FContext(ctx context.Context, req *demo.Req) (res *demo.Res, err error) {
addr := ""
attachment := ctx.Value(constant.AttachmentKey).(map[string]interface{})
if v, ok := attachment["socket.addr"]; ok {
addr = v.(string)
}
fmt.Println("test context, addr:", addr)
return
}
**发现这个attachment是nil ,如下图 **

Anything else we need to know?: 完整示例请参考: https://gitee.com/lethexixin/grpc-context-error.git
Unfortunately, attachment feature is exclusive for dubbo protocol, that is, gRPC not supports attachment. So, please consider using other way to pass your own data. BTW, please leave a comment on #2, thanks for your cooperation.
@xavier-niu 谢谢,查资料才发现在 grpc 中,client 与 server 之间通过 context 传递上下文数据的时候,不能使用 context.WithValue,因为 server 端无法获取到 client 自定义的 key, 不过我们可以使用 grpc 提供的 medadata 接口:
//客户端:
func main() {
req := &demo.Req{}
res := &demo.Res{}
ctx := metadata.NewOutgoingContext(context.Background(), metadata.Pairs("socket.addr", "127.0.0.1:12788"))
err := consumer.GetContextImpl().FContext(ctx, req, res)
}
//服务端:
func (g *Provider) FContext(ctx context.Context, req *demo.Req) (res *demo.Res, err error) {
if md, ok := metadata.FromIncomingContext(ctx); ok {
xIds := md.Get("socket.addr")
fmt.Println("xIds:",xIds)
}
return
}
如此,服务端就可以拿到context的值了,不过这个metadata方式只能传string类型
参考:https://mp.weixin.qq.com/s/cwkfYA2rgNIbHom5Yoeizg

最后:或许可以在 dubbo-go-samples/context 模块的readme.md 文件中描述一下grpc中关于context的问题及解决方案,避免别的小伙伴入坑😳
Thank you for the valuable information. cc @LaurenceLiZhixin