欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

golanggrpc中metadata的使用

时间:2023-06-18

gRPC让我们可以像本地调用一样实现远程调用,对于每一次的RPC调用中,都可能会有一些在header中传递的数据,而这些数据就可以通过metadata来传递。

metadata是以key-value的形式存储数据的,其中key是string类型,value是[]string类型,即一个字符串切片类型。metadata使得client和server能够为对方提供关于本次调用的一些信息,就像一次http请求的RequestHeader和ResponseHeader一样。http中header的生命周期是一次http请求,那么metadata的生命周期就是一次RPC调用。

1、go中使用metadata

项目源代码路径:https://github.com/grpc/grpc-go/tree/master/metadata

项目文档:https://github.com/grpc/grpc-go/blob/master/documentation/grpc-metadata.md

 使用的go包:"google.golang.org/grpc/metadata"

1)新建metadata

MD 类型实际上是map,key是string,value是string类型的slice。

type MD map[string][]string

创建的时候可以像创建普通的map类型一样使用new关键字进行创建:

//第一种方式md := metadata.New(map[string]string{"key1": "val1", "key2": "val2"})//第二种方式 key不区分大小写,会被统一转成小写md := metadata.Pairs( "key1", "val1", "key1", "val1-2", // "key1" will have map value []string{"val1", "val1-2"} "key2", "val2",)

2)发送metadata

md := metadata.Pairs("key", "val")// 新建一个有 metadata 的 contextctx := metadata.NewOutgoingContext(context.Background(), md)// 单向 RPCresponse, err := client.SomeRPC(ctx, someRequest)

3)接收metadata

func (s *server) SomeRPC(ctx context.Context, in *pb.SomeRequest) (*pb.SomeResponse, err) { md, ok := metadata.FromIncomingContext(ctx) // do something with metadata}

2.gRPC中使用metadata 1)proto

syntax = "proto3";option go_package = "./;proto";service Greeter { rpc SayHello (HelloRequest) returns (HelloReply) {}}message HelloRequest { string name = 1;}message HelloReply { string message = 1;}

执行命令编译文件,生成.pb.go文件:protoc -I 、test.proto --go_out=plugins=grpc:.

2)client 

package mainimport ("context""fmt""go-class/rpc/07metadata/proto""google.golang.org/grpc""google.golang.org/grpc/metadata")func main() {conn, err := grpc.Dial(":8083", grpc.WithInsecure())if err != nil {panic(err)}defer conn.Close()c := proto.NewGreeterClient(conn)//写入metadata***********md := metadata.New(map[string]string{"name": "lff","password": "123456",})ctx := metadata.NewOutgoingContext(context.Background(), md)r, err := c.SayHello(ctx, &proto.HelloRequest{Name: "lff111"})if err != nil {panic(err)}fmt.Println(r.Message)}

3)server

package mainimport ("context""fmt""net""google.golang.org/grpc""google.golang.org/grpc/metadata""go-class/rpc/07metadata/proto")type Server struct {}func (s *Server) SayHello(ctx context.Context, req *proto.HelloRequest) (*proto.HelloReply, error) { //获取header*********md, ok := metadata.FromIncomingContext(ctx)if ok {fmt.Println("get metadata error")}for key, val := range md {fmt.Println(key, val)} //获取header中的name*********//if nameSlice, ok := md["name"]; ok {//fmt.Println(nameSlice)//for i, e := range nameSlice {//fmt.Println(i, e)//}//}return &proto.HelloReply{Message: "Hello " + req.Name,}, nil}func main(){g := grpc.NewServer()proto.RegisterGreeterServer(g, &Server{})lis, err := net.Listen("tcp", "127.0.0.1:8083")if err != nil {panic("failed to listen:" + err.Error())}err = g.Serve(lis)if err != nil {panic("failed to start grpc:" + err.Error())}}

先启动server,在启动client端,结果看到打印出的header

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。