m## 1.grpc的metadata
类比学习:
HTTP协议
中
Header
一样存储一些
key-value
格式的数据。
grpc
底层采用的是
http2
也有支持传递数据,使用的就是
metadata
。
在metadata中key的类型是字符串,而value是[]string。HTTP中header的生命周期是一次http请求,metadata的生命周期与header一样,metadata的生命周期是一次RPC调用。
2.创建metadata
创建metadata可以像创建普通的map类型类似,使用
metadata
下的
new
方法进行创建。
也可以使用
metadata
下的
Pairs
方法进行创建
md := metadata.Pairs(
"k1","v1",
"k1","v2",//"k1" will have map value []string{"v1","v2"}
"k2","v3",
)
k不区分大小写,会被同一转换为小写!
3.发送metadata
// 创建一个metadata
md := metadata.Pairs("k1","v1")
// 使用metadata下的NewOutGoingContext,将md装到context.Background()中,并替代之前的ctx
ctx := metadata.NewOutGoingContest(context.Background(),md)
4. 接受metadata
使用
metadata
下的
FromInComingContext
方法获取context中的metadata
5.详细代码演示
5.1 proto
syntax = "proto3";
option go_package = "../proto";
service MyMetadata {
rpc testMetadata (metadataRequest) returns (metadataResponse);
}
message metadataRequest {
string data = 1;
}
message metadataResponse {
string data = 1;
}
5.2 server
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"
"metadataTest/proto"
"net"
)
type Server struct{}
func (s *Server) TestMetadata(ctx context.Context, request *proto.MetadataRequest) (*proto.MetadataResponse, error) {
md,_ := metadata.FromIncomingContext(ctx)
fmt.Printf("username:%T",md["username"][0])
data := "req:" + request.Data + "/res:ok"
return &proto.MetadataResponse{Data: data}, nil
}
func main() {
s := Server{}
g := grpc.NewServer()
proto.RegisterMyMetadataServer(g, &s)
conn, err := net.Listen("tcp", ":8088")
if err != nil {
panic(err)
}
_ = g.Serve(conn)
}
5.3 client
package main
import (
"context"
"fmt"
"google.golang.org/grpc"
"google.golang.org/grpc/metadata"
"metadataTest/proto"
)
func main() {
conn, _ := grpc.Dial("127.0.0.1:8088", grpc.WithInsecure())
defer conn.Close()
c := proto.NewMyMetadataClient(conn)
data := &proto.MetadataRequest{Data: "request"}
md := metadata.Pairs(
"username","spl",
)
ctx := metadata.NewOutgoingContext(context.Background(),md)
response, _ := c.TestMetadata(ctx, data)
fmt.Println(response.Data)
}