go-zero icon indicating copy to clipboard operation
go-zero copied to clipboard

context 内容丢失

Open ha666 opened this issue 1 year ago • 1 comments
trafficstars

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的值,但是实际上没有得到。

test0218.zip

ha666 avatar Feb 18 '24 08:02 ha666

确实存在这个问题,丢失了。ctx中有transport.connectionKey、peer.peerKey、metadata.mdIncomingKey、grpc.streamKey、baggage.baggageContextKeyType、trace.traceContextKeyType、trace.traceContextKeyType,在没有解决之前可以通过 md 来传递额外数据,测试也没有问题。

eyjian avatar Feb 19 '24 02:02 eyjian

我的天。 ctx本来就不是用来在网络间传输数据的,grpc必须使用metadata传输元数据。 如果需要将ctx的数据自动转入md,得编写拦截器做转换。

reatang avatar Feb 20 '24 10:02 reatang

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.

Issues-translate-bot avatar Feb 20 '24 10:02 Issues-translate-bot

Not a problem.

kevwan avatar Feb 25 '24 09:02 kevwan