GRPC开发全攻略:从环境搭建到代码实现

目录

1、开发环境准备

2、编写proto,定义调用函数

1、普通模式

2、客户端流式

3、服务端流式

4、双端流式

3、编译proto,生成golang源码

4、grpc 服务端代码实现

5、grpc 客户端代码实现

6、运行代码,查看运行结果


1、开发环境准备

要使用grpc,首先需要安装Protocol Buffers 工具,不同的平台对应不同的包,我们都可以从这里下载到:

https://github.com/protocolbuffers/protobuf/releases/tag/v29.3

如果你是linux环境,可以下载:protoc-29.3-linux-x86_64.zip。

如果是mac环境,现在苹果基本都是自研的cpu,下载:protoc-29.3-osx-aarch_64.zip.

win环境下载:protoc-29.3-win64.zip。

这个工具可以将proto文件转换为对应语言的代码,是使用grpc必不可少的一环。

下载完成后,要将对应的可执行文件放到PATH目录下,比如我的protoc目录如下:

需要将对应的目录加到PATH目录:

export PATH=/Users/liupeng/Documents/binary/bin:$PATH

查看protoc版本:

 安装golang插件:

# 用于将 *.proto 文件生成一个后缀为 *.pb.go 的文件。生成文件中包含所有 .proto 文件中定义的类型及其序列化方法
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest

# 用于生成 gRPC 服务端需要实现的接口
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest

将GOPATH/bin目录添加到PATH中:

export PATH=/Users/liupeng/go/bin:$PATH

 这一步很重要,否则无法编译proto生成golang代码。

2、编写proto,定义调用函数

grpc函数支持4种模式,分别为普通模式、客户端流式、服务端流式、双端流式,四种模式的定义分别如下介绍。

1、普通模式

客户端发送请求到服务端,服务端实时响应,返回数据给客户端,如普通的函数调用一般。

rpc SayHello (HelloRequest) returns (HelloReply) {}

2、客户端流式

客户端向服务端发送流式请求,可以多次写入数据,服务端循环获取客户端数据,直到客户端关闭该流。服务端接收完所有数据并处理后,向客户端返回一个普通响应。

rpc ClientStreamingSayHello(stream HelloRequest) returns (HelloReply) {}

3、服务端流式

客户端向服务端发送请求,服务端发送流到客户端,客户端从流中读取数据,直到服务端关闭该流。

rpc ServerStreamingSayHello(HelloRequest) returns (stream HelloReply) {}

4、双端流式

这就比较容易理解了,上报、下发数据都以流式方式进行。

rpc BidirectionalStreamingSayHello(stream HelloRequest) returns (stream HelloReply) {}

完整的proto代码放到文章最后,需要的同学可以自取。

3、编译proto,生成golang源码

server端,编译proto,生成golang源码:

protoc --go_out=. --go-grpc_out=. hello.proto

client端一样的道理,编译hello.proto:

 

4、grpc 服务端代码实现

我们一共注册了四个函数,在服务端需要分别实现其业务逻辑,我们只实现将收到的信息返回回去,simple rpc函数实现如下:

func (s *Server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
    fmt.Println("Received:", in.GetName())
    return &pb.HelloReply{Message: "Hello " + in.GetName()}, nil
}

双端流式实现如下:

func (s *Server) BidirectionalStreamingSayHello(stream pb.Greeter_BidirectionalStreamingSayHelloServer) error {
    for {
        in, err := stream.Recv()
        if err == io.EOF {
            return nil
        }
        if err != nil {
            return err
        }
        fmt.Println("bidirectional request received:", in)
        if err := stream.Send(&pb.HelloReply{Message: "bidirectional done"}); err != nil {
            return err
        }
    }
}

5、grpc 客户端代码实现

客户端代码实现,simple rpc与双端流失放到了一起:

func main() {
    flag.Parse()
    conn, err := grpc.NewClient(*addr, grpc.WithTransportCredentials(insecure.NewCredentials()))
    if err != nil {
        fmt.Println("did not connect: ", err)
    }
    defer conn.Close()
    c := pb.NewGreeterClient(conn)
    // Contact the server and print out its response.
    ctx, cancel := context.WithTimeout(context.Background(), time.Second)
    defer cancel()
    // --------普通请求方式------- //
    r, err := c.SayHello(ctx, &pb.HelloRequest{Name: *name})
    if err != nil {
        fmt.Println("could not greet: ", err)
    }
    fmt.Println("Greeting: ", r.GetMessage())
    // --------双向流式请求方式------- //
    bstream, err := c.BidirectionalStreamingSayHello(ctx)
    if err != nil {
        fmt.Println("could not open stream: ", err)
        return
    }
    go func() {
        // 异步发送信息
        for i := 0; i < 10; i++ {
            bstream.Send(&pb.HelloRequest{Name: "bidirection stream client"})
        }
        bstream.CloseSend()
    }()
    fmt.Printf("response:\n")
    for {
        r, err := bstream.Recv()
        if err != nil {
            break
        }
        fmt.Printf(" - %s\n", r.Message)
    }
}

6、运行代码,查看运行结果

可以看到普通模式,以及双端流式都正常运行了。

grpc还有异步使用模式,nvidia的triton server就是使用的异步模式,后面再单独介绍。

所有代码都已经上传到github了,需要的同学可自由获取:

https://github.com/liupengh3c/career/tree/main/grpc

 都到这里了,小伙伴们点个关注呗~~~~~~~~~。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值