go控制grpc的metadata

grpc让我们可以像本地调用一样实现远程调用,对于每一次的RPC调用中,都可能会有一些有用的数据,而这些数据就可以通过
metadata来传递。metadata是以key-value的形式存储数据的,其中key是string类型,而value是[]string,即一个字符串
数组类型。metadata使得client和server能够为对方提供关于本次调用的一些信息,就像一次http请求的RequestHeader和
ResponseHeader一样。http中header的生命周周期是一次http请求,那么metadata的生命周期就是一次rpc调用。

go中使用metadata

新建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",
  "key2": "val2",
}

发送metadata

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

接收metadata

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

grpc中使用metadata

proto

syntax = "proto3"
option go_package=".;proto"

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply){}
}

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}

server

type Server struct{}

func (s *Server) SayHello(ctx context.Context, request *proto.HelloRequest)(*proto.HelloReply, error){
  md, ok := metadata.FromIncomingContext(ctx)
  if ok{
    fmt.Println("get metadata error")
    return
  }
  if nameSlice, ok := md["name"];ok{
    fmt.Println(nameSlice)
    for _, val := range nameSlice{
      fmt.Println(val)
    }
  }
  for key, val := range md{
    fmt.Println(key, val)
  }
  return &proto.HelloReply{
    Message: "hello" + request.Name,
  }, nil
} 

func main(){
  g := grpc.NewServer()
  proto.RegisterGreeterServer(g, &Server{})
  lis, err := net.Listen("tcp", "0.0.0.0:50051")
  if err != nil{
    panic("failed to listen"+err.Error)
  }
  err = g.Serve(lis)
  if err != nil{
    panic(err)
  }
}

client

package main
import (
  "context"
  "fmt"
  "google.golang.org/grpc"
  "google.golang.org/grpc/metadata"
  "time"
  "OldPackageTest/grpc_test/proto"
)

func main(){
  conn, err := grpc.Dial("127.0.0.1:50051", grpc.WithInsecure())
  if err != nil{
    panic(err)
  }
  defer conn.Close()
  c := proto.NewGreeterClient(conn)
  md := metadata.Pairs("timestamp", time.Now().Format(timestampFormat))
  ctx := metadata.NewOutgoingContext(context.Background(), md)
  r, err := c.SayHello(context.Background(), &proto.HelloRequest{Name:"bobby"})
  if err != nil{
    panic(err)
  }
  fmt.Println(r.Message)
}
posted @ 2022-08-02 13:40  我在路上回头看  阅读(426)  评论(0)    收藏  举报