grpc-环境与示例

1. 数据传输基本原理

image

2. grpc环境安装

  • 代码生成器
go get -u github.com/golang/protobuf/protoc-gen-go
// 会自动在 $GOPATH/bin 目录下生成 protoc-gen-go 可执行二进制文件
// 需要设置GOPATH环境变量,并且将 $GOPATH/bin 添加到系统或当前用户的环境变量PATH中
  • grpc框架
go get -u google.golang.org/grpc
  • Proto buffer 文件编译器
1. 下载地址: https://github.com/protocolbuffers/protobuf/releases
2. 下载编译器 protoc
3. 将编译器放在 $GOPATH/bin/目录下
4. 将$GOPATH/bin/目录添加到系统或当前用户环境变量 PATH 中
# protoc编译器会依据proto文件生成对应语言的代码

3. Demo

  • 编写 proto buffer文件
syntax = "proto3"; // 声明当前使用的是proto3语法

option go_package = "service/"; // option --选项,指明依据当前proto文件生成的go代码放到哪个包下

// 定义rpc消息结构 -- 请求
message ProductRequest {
  int64 product_id = 1;
}

// 定义rcp消息结构 -- 响应
message ProductResponse {
  int64 product_store = 1;            // 字段类型 字段名 字段值在二进制数据中的排序位置
}
  • 使用 protoc编译 proto文件,生成Go代码
protoc --go_out=service proto/hai.proto
// --go_out 指定生成go代码保存的目录位置,最后一个参数是proto文件
// 会生成一个 *.pb.go 文件
  1. grpc服务端与客户端
  • 定义 proto buffer文件
syntax = "proto3";

option go_package = "service/";

message ProductRequest {
  int64 product_id = 1;
}

message ProductResponse {
  int64 product_store = 1;
}

// 定义一个产品服务
service ProductService {
  // GetProductStoreNums 获取商品库存
  rpc GetProductStoreNums (ProductRequest) returns (ProductResponse);
}
  • Protoc 编译 proto文件
protoc --go_out=plugins=grpc:. .protoshop.proto
// 指定插件 plugins=grpc
// 冒号后面是生成Go代码的保存目录

// 生成代码之后,需执行 go mod tidy 安装依赖
  • 创建grpc服务端
package main

import (
   "context"
   "fmt"
   "google.golang.org/grpc"
   "learn-go-project/service"
   "log"
   "net"
)

// ImplementProductService 定义产品服务实现类
type ImplementProductService struct {
   
}

// GetProductStoreNums 实现 proto buffer文件中service 定义的rpc方法 ==> 实现 pb文件中 rpc方法生成的接口
func (s *ImplementProductService) GetProductStoreNums(ctx context.Context, in *service.ProductRequest) (*service.ProductResponse, error) {
   fmt.Println(in.GetProductId())
   return &service.ProductResponse{ProductStore: 20}, nil
}

func main() {
   // 1. 声明一个grpc服务
   grpcService := grpc.NewServer()

   // 2. 将实现类注册到生成的pd文件中
   service.RegisterProductServiceServer(grpcService, &ImplementProductService{})

   // 3. 启动tcp服务
   l, err := net.Listen("tcp", "0.0.0.0:9999")
   if err != nil {
      log.Fatalln(err)
   }

   // 3. 让grp去处理tcp连接
   err = grpcService.Serve(l)
   if err != nil {
      log.Fatalln(err)
   }
}
  • 创建grpc客户端
package main

import (
   "context"
   "fmt"
   "google.golang.org/grpc"
   "learn-go-project/service"
   "log"
)

func main() {
   // 1. 创建grpc客户端连接
   conn, err := grpc.Dial(":9999", grpc.WithInsecure())
   if err != nil {
      log.Fatalln(err)
   }
   defer conn.Close()

   // 2. 创建对应服务的连接
   cli := service.NewProductServiceClient(conn)
   
   // 3. 调用方法,获取响应体
   response, err := cli.GetProductStoreNums(context.Background(), &service.ProductRequest{ProductId: 50})
   if err != nil {
      log.Fatalln(err)
   }
   
   fmt.Println(response.ProductStore)
}
原文地址:https://www.cnblogs.com/2bjiujiu/p/15191961.html