gRPC之metadata入门案例【附完整源码】

目录结构
gRPC之metadata入门案例【附完整源码】

go.mod

module grpc_demo

go 1.16

require (
   github.com/golang/protobuf v1.5.2 // indirect
   google.golang.org/grpc v1.39.0
   google.golang.org/protobuf v1.26.0
)

hello.proto

生成代码命令:protoc -I . stream.proto --go_out=plugins=grpc:.

proto完整代码:

syntax = "proto3";

// 引入第三方的proto
import "google/protobuf/empty.proto";
import "google/protobuf/timestamp.proto";

option go_package = "../proto";

service Greeter{
  rpc Ping(google.protobuf.Empty) returns (Pong);
}

// 枚举类型
enum Gender{
  MALE = 0;
  FEMALE = 1;
}

message Pong{
  string name = 1; // 姓名
  int32 age = 2; // 年龄
  Gender gender = 3; // 性别
  map<string, string> skill = 4; // 技能
  google.protobuf.Timestamp birthDay = 5;// 生日
}

server.go

package main

import (
   "context"
   "fmt"
   "google.golang.org/grpc/metadata"
   "grpc_demo/zdp09_time_message/proto"
   "net"
   "time"

   "github.com/golang/protobuf/ptypes/empty"
   "google.golang.org/grpc"
   "google.golang.org/protobuf/types/known/timestamppb"
)

const PORT = ":50052"

type Server struct {
}

func (s *Server) Ping(ctx context.Context, request *empty.Empty) (*proto.Pong, error) {
   //接收metadata
   md, ok := metadata.FromIncomingContext(ctx)
   if ok {
      fmt.Println("get metadata")
      // 从metadata中提取内容
      if nameSlice, ok := md["name"]; ok {
         // 是一个slice
         fmt.Println("nameSlice: ", nameSlice)
         // 从slice中提取内容
         for name, err := range nameSlice {
            fmt.Println(name, err)
         }
      }
   }

   // 返回内容
   return &proto.Pong{
      Name:   "张大鹏",
      Age:    22,
      Gender: proto.Gender_MALE, // 使用枚举类型
      Skill: map[string]string{
         "Java":   "80%",
         "Python": "95%",
         "Go":     "90%",
      },
      BirthDay: timestamppb.New(time.Now()),
   }, nil
}

func main() {
   // 监听端口
   lis, err := net.Listen("tcp", PORT)
   if err != nil {
      panic(err)
   }
   // 创建grpc服务
   s := grpc.NewServer()
   // 注册grpc服务
   proto.RegisterGreeterServer(s, &Server{})
   // 启动grpc服务
   err = s.Serve(lis)
   if err != nil {
      panic(err)
   }
}

client.go

package main

import (
	"context"
	"fmt"
	"google.golang.org/grpc/metadata"
	"grpc_demo/zdp09_time_message/proto"

	"github.com/golang/protobuf/ptypes/empty"
	"google.golang.org/grpc"
)

func main() {
	conn, err := grpc.Dial("localhost:50052", grpc.WithInsecure())
	if err != nil {
		panic(err)
	}
	defer conn.Close()
	c := proto.NewGreeterClient(conn)
	// 创建metadata
	md := metadata.New(map[string]string{
		"name":     "zhangdapeng",
		"password": "zhangdapeng",
	})

	// 将metadata写入context上下文
	ctx := metadata.NewOutgoingContext(context.Background(), md)

	// ping:携带metadata
	pingResponse, err := c.Ping(ctx, &empty.Empty{})

	if err != nil {
		panic(err)
	}
	fmt.Println(pingResponse.Name, pingResponse.Age, pingResponse.Gender, pingResponse.Skill, pingResponse.BirthDay)
}

运行测试

服务端控制台输出
gRPC之metadata入门案例【附完整源码】

客户端控制台输出
gRPC之metadata入门案例【附完整源码】

上一篇:Kubernetes 中的 gRPC 负载均衡


下一篇:go语言中probuf与客户端的交互