栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

golang grpc中metadata的使用

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

golang grpc中metadata的使用

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 的 context
ctx := metadata.NewOutgoingContext(context.Background(), md)

// 单向 RPC
response, 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 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)

	//写入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) {
    //获取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

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/735601.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号