go-zero
go-zero copied to clipboard
context 内容丢失
golang版本:1.21.6 go-zero版本:1.6.2
客户端代码:
package main
import (
"context"
"fmt"
"log"
"test0218/test0218"
"github.com/zeromicro/go-zero/core/conf"
"github.com/zeromicro/go-zero/zrpc"
"google.golang.org/grpc"
)
type (
Request = test0218.Request
Response = test0218.Response
Test0218 interface {
Ping(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error)
}
defaultTest0218 struct {
cli zrpc.Client
}
)
func NewTest0218(cli zrpc.Client) Test0218 {
return &defaultTest0218{
cli: cli,
}
}
func (m *defaultTest0218) Ping(ctx context.Context, in *Request, opts ...grpc.CallOption) (*Response, error) {
client := test0218.NewTest0218Client(m.cli.Conn())
return client.Ping(ctx, in, opts...)
}
func main() {
var clientConf zrpc.RpcClientConf
conf.MustLoad("etc/greet-client.yaml", &clientConf)
client := NewTest0218(zrpc.MustNewClient(clientConf))
i:=100
ctx := context.TODO()
ctx = context.WithValue(ctx, "request_id", fmt.Sprintf("request-%d", i))
ctx = context.WithValue(ctx, "abc", fmt.Sprintf("abc-%d", i))
resp, err := client.Ping(ctx, &test0218.Request{})
if err != nil {
log.Fatal(err)
return
}
log.Println(resp)
}
服务端代码:
package server
import (
"context"
"fmt"
"test0218/internal/logic"
"test0218/internal/svc"
"test0218/test0218"
)
type Test0218Server struct {
svcCtx *svc.ServiceContext
test0218.UnimplementedTest0218Server
}
func NewTest0218Server(svcCtx *svc.ServiceContext) *Test0218Server {
return &Test0218Server{
svcCtx: svcCtx,
}
}
func (s *Test0218Server) Ping(ctx context.Context, in *test0218.Request) (*test0218.Response, error) {
fmt.Printf("abc:%+v\n",ctx.Value("abc"))
fmt.Printf("request_id:%+v\n",ctx.Value("request_id"))
l := logic.NewPingLogic(ctx, s.svcCtx)
return l.Ping(in)
}
我期望的是,在服务端可以获取到context中的abc和request_id的值,但是实际上没有得到。
确实存在这个问题,丢失了。ctx中有transport.connectionKey、peer.peerKey、metadata.mdIncomingKey、grpc.streamKey、baggage.baggageContextKeyType、trace.traceContextKeyType、trace.traceContextKeyType,在没有解决之前可以通过 md 来传递额外数据,测试也没有问题。
我的天。 ctx本来就不是用来在网络间传输数据的,grpc必须使用metadata传输元数据。 如果需要将ctx的数据自动转入md,得编写拦截器做转换。
Bot detected the issue body's language is not English, translate it automatically. 👯👭🏻🧑🤝🧑👫🧑🏿🤝🧑🏻👩🏾🤝👨🏿👬🏿
Oh My God. ctx is not originally used to transmit data between networks. grpc must use metadata to transmit metadata. If you need to automatically transfer ctx data to md, you must write an interceptor for conversion.
Not a problem.