文章目录
1.grpc框架实现小demo(详细理解)
1.1 定义的proto文件
syntax = "proto3";
// 定义包名
package test;
option go_package="./test";
//定义多个服务,每个服务内可以定义多个接口
service Waiter{
//方法(请求消息结构体)returns (返回消息结构体){}
rpc DOMD5(Req) returns (Res){}
}
//定义消息结构
message Req{
string jsonStr=1;
}
message Res{
string backjson=1;
}
1.2 编写server端代码
package main
import (
t "../test"
"context"
"crypto/md5"
"fmt"
"google.golang.org/grpc"
"google.golang.org/grpc/reflection"
"log"
"net"
)
//业务实现方法容器
type server2 struct {
}
/**
server 定义DOMD5 内部处理请求并且返回结果
参数: context.Context固定,*t.Req[相应接口的请求参数]
返回参数:*t.Res 相应接口的返回参数
*/
func (s *server2 ) DOMD5(ctx context.Context, in *t.Req ) (*t.Res,error){
fmt.Println("DOMD5方法请求JSON:"+in.JsonStr)
return &t.Res{Backjson: "MD5:" + fmt.Sprintf("%x", md5.Sum([]byte(in.JsonStr)))},nil
}
func main() {
lis,err:=net.Listen("tcp","127.0.0.1:8000") //监听TCP连接
if err!=nil{
log.Fatalf("监听失败:%v",err)
}
s:=grpc.NewServer() //创建grpc服务
/*注册接口服务
是以proto文件中定义的service为单位进行注册,服务中可以有多个方法
proto编译的时候会为每个service生成Register×××Service方法
注册接口格式:包.注册服务方法(grpc服务实例,包含接口方法的结构体)*/
t.RegisterWaiterServer(s,&server2{})
//当有多个可以注册的接口服务时,结构体要实现对应的接口方法
//在grpc上注册反射服务
reflection.Register(s)
//将监听交给grpc的服务处理
err=s.Serve(lis)
if err!=nil{
log.Fatalf("fail to serve:%v",err)
}
}
1.2 编写client端代码
package main
import (
t "../test"
"context"
"google.golang.org/grpc"
"log"
"os"
)
func main() {
//建立连接到grpc服务
con,err:=grpc.Dial("127.0.0.1:8000",grpc.WithInsecure())
if err!=nil{
log.Fatalf("did not connect:%v",err)
}
//函数结束时关闭连接
defer con.Close()
//创建客户端 方法也是由proto 编译时自动生成的
c:=t.NewWaiterClient(con)
res:="hello111"
if len(os.Args)>1{
res=os.Args[1]
}
r,err2:=c.DOMD5(context.Background(),&t.Req{JsonStr: res})
if err2!=nil{
log.Fatalf("fail to DOMD5 %v",err2)
}
log.Printf("服务端响应:"+r.Backjson)
}
1.3 先启动server端,再启动client端
- 服务端收到请求,并且能够成功响应
2.grpc拦截器初认识
gRPC作为通用RPC框架,内置了拦截器功能。包括服务器端的拦截器和客户端拦截器。
主要作用是在rpc调用的前后进行额外处理。
从客户端角度讲,可以在请求发起前,截取到请求参数并修改;也可以修改服务器的响应参数。
2.1 gRPC 的拦截分类
-
按功能来分
一元拦截器 UnaryInterceptor
流式拦截器 StreamInterceptor -
按端来分
客户端拦截器 ClientInterceptor
服务端拦截器 ServerInterceptor
2.2 一元拦截器
函数原型:
type UnaryServerInterceptor func(ctx context.Context, req interface{}, info *UnaryServerInfo, handler UnaryHandler) (resp interface{}, err error)
要完成一个拦截器需要实现 UnaryServerInterceptor
方法。形参如下:
- ctx context.Context:请求上下文
- req interface{}:RPC 方法的请求参数
- info *UnaryServerInfo:RPC 方法的所有信息
- handler UnaryHandler:RPC 方法本身
2.3 流式拦截器
函数原型:
type StreamServerInterceptor func(srv interface{}, ss ServerStream, info *StreamServerInfo, handler StreamHandler) error