当前位置:网站首页>Use of metadata in golang grpc

Use of metadata in golang grpc

2022-07-05 23:01:00 sweey_ lff

gRPC Let's implement remote calls like local calls , For every time RPC in call , There may be some in header Data passed in , And these data can be passed through metadata To pass on .

metadata In order to key-value Storage of data in the form of , among key yes string type ,value yes []string type , That is, a string slice type .metadata bring client and server It can provide the other party with some information about this call , It's like once http Requested RequestHeader and ResponseHeader equally .http in header The life cycle of is a http request , that metadata The life cycle of is once RPC call .

1. go Use in metadata

Project source code path :https://github.com/grpc/grpc-go/tree/master/metadata

Project documentation :https://github.com/grpc/grpc-go/blob/master/Documentation/grpc-metadata.md

  The use of go package :"google.golang.org/grpc/metadata"

1) newly build metadata

MD The type is actually map,key yes string,value yes string Type of slice.

type MD map[string][]string

When creating, you can create ordinary map Use the same type new Keyword to create :

// The first way 
md := metadata.New(map[string]string{"key1": "val1", "key2": "val2"})

// The second way  key Case insensitive , Will be uniformly converted to lowercase 
md := metadata.Pairs(
    "key1", "val1",
    "key1", "val1-2", // "key1" will have map value []string{"val1", "val1-2"}
    "key2", "val2",
)

2) send out metadata

md := metadata.Pairs("key", "val")

//  A new one with  metadata  Of  context
ctx := metadata.NewOutgoingContext(context.Background(), md)

//  A one-way  RPC
response, err := client.SomeRPC(ctx, someRequest)

3) receive 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 Use in 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;
}

Execute the command to compile the file , Generate .pb.go file :protoc -I . test.proto --go_out=plugins=grpc:.

2)client 

package main

import (
	"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)

	// write in 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 main

import (
	"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) {
    // obtain header*********
	md, ok := metadata.FromIncomingContext(ctx)
	if ok {
		fmt.Println("get metadata error")
	}
	for key, val := range md {
		fmt.Println(key, val)
	}
    // obtain header Medium 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())
	}
}

Start... First server, Start up client End , As a result, I saw the printed header

原网站

版权声明
本文为[sweey_ lff]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/02/202202140347420525.html