Go GRPC之拦截器

grpc服务端和客户端都提供了interceptor功能,功能类似middleware,很适合在这里处理验证、日志等流程,话不多说直接上代码

1.编写helloworld.proto

 

 并用命令生成相应的go文件,生成的文件内容如下:

// Code generated by protoc-gen-go-grpc. DO NOT EDIT.

package proto

import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)

// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7

// GreeterServerClient is the client API for GreeterServer service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type GreeterServerClient interface {
SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error)
}

type greeterServerClient struct {
cc grpc.ClientConnInterface
}

func NewGreeterServerClient(cc grpc.ClientConnInterface) GreeterServerClient {
return &greeterServerClient{cc}
}

func (c *greeterServerClient) SayHello(ctx context.Context, in *HelloRequest, opts ...grpc.CallOption) (*HelloReply, error) {
out := new(HelloReply)
err := c.cc.Invoke(ctx, "/helloworld.GreeterServer/SayHello", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}

// GreeterServerServer is the server API for GreeterServer service.
// All implementations must embed UnimplementedGreeterServerServer
// for forward compatibility
type GreeterServerServer interface {
SayHello(context.Context, *HelloRequest) (*HelloReply, error)
mustEmbedUnimplementedGreeterServerServer()
}

// UnimplementedGreeterServerServer must be embedded to have forward compatible implementations.
type UnimplementedGreeterServerServer struct {
}

func (UnimplementedGreeterServerServer) SayHello(context.Context, *HelloRequest) (*HelloReply, error) {
return nil, status.Errorf(codes.Unimplemented, "method SayHello not implemented")
}
func (UnimplementedGreeterServerServer) mustEmbedUnimplementedGreeterServerServer() {}

// UnsafeGreeterServerServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to GreeterServerServer will
// result in compilation errors.
type UnsafeGreeterServerServer interface {
mustEmbedUnimplementedGreeterServerServer()
}

func RegisterGreeterServerServer(s grpc.ServiceRegistrar, srv GreeterServerServer) {
s.RegisterService(&GreeterServer_ServiceDesc, srv)
}

func _GreeterServer_SayHello_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(HelloRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(GreeterServerServer).SayHello(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/helloworld.GreeterServer/SayHello",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(GreeterServerServer).SayHello(ctx, req.(*HelloRequest))
}
return interceptor(ctx, in, info, handler)
}

// GreeterServer_ServiceDesc is the grpc.ServiceDesc for GreeterServer service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var GreeterServer_ServiceDesc = grpc.ServiceDesc{
ServiceName: "helloworld.GreeterServer",
HandlerType: (*GreeterServerServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "SayHello",
Handler: _GreeterServer_SayHello_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "helloworld.proto",
}
2.服务端文件server.go
package main

import (
"OldPacketTest/grpc_test/proto"
"context"
"fmt"
"google.golang.org/grpc"
"net"
)

type Server struct {
proto.UnimplementedGreeterServerServer
}

func (s *Server) SayHello(ctx context.Context, req *proto.HelloRequest) (*proto.HelloReply, error) {
return &proto.HelloReply{
Message: "hello " + req.Name,
}, nil
}

func main() {
interceptor := func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) {
fmt.Println("接收到了一个新的请求")
return handler(ctx, req)
}
opt := grpc.UnaryInterceptor(interceptor)
g := grpc.NewServer(opt)
proto.RegisterGreeterServerServer(g, &Server{})
lis, err := net.Listen("tcp", "0.0.0.0:8081")
if err != nil {
panic("failed to listen:" + err.Error())
}
err = g.Serve(lis)
if err != nil {
panic("failed to start grpc:" + err.Error())
}
}

3.客户端文件client.go
package main

import (
"OldPacketTest/grpc_test/proto"
"context"
"fmt"
"google.golang.org/grpc"
"time"
)

func main() {
interceptor := func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
start := time.Now()
err := invoker(ctx, method, req, reply, cc, opts...)
fmt.Printf("耗时:%s\n", time.Since(start))
return err
}
var opts []grpc.DialOption
opts = append(opts, grpc.WithInsecure())
opts = append(opts, grpc.WithUnaryInterceptor(interceptor))
conn, err := grpc.Dial("127.0.0.1:8081", opts...)
if err != nil {
panic(err)
}
defer conn.Close()

c := proto.NewGreeterServerClient(conn)
r, err := c.SayHello(context.Background(), &proto.HelloRequest{
Name: "bobby",
})
if err != nil {
panic(err)
}
fmt.Println(r.Message)
}
 
posted @ 2023-02-12 20:55  lisus2000  阅读(179)  评论(0编辑  收藏  举报