• 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)
    }
    
  • 相关阅读:
    sourceInsight4 破解笔记(完美破解)
    notepad++ 查找引用(Find Reference)(适用于c c++及各类脚本比如lua、python等)
    notepad++ 插件推荐——快速定位文件
    WebRTC开源项目一览之二
    编译最新版webrtc源码和编译好的整个项目10多个G【分享】
    Neo4j中实现自定义中文全文索引
    NEO4J -模糊查询
    neo4j数据库迁移---------Neo4j数据库导入导出的方法
    使用neo4j图数据库的import工具导入数据 -方法和注意事项
    neo4j采坑记
  • 原文地址:https://www.cnblogs.com/weiweivip666/p/16543396.html
Copyright © 2020-2023  润新知