go使用protoc-gen插件编译protobuf文件及构建gRPC的服务

作者:程序员CKeen
博客:http://ckeen.cn​​​​​​​​​​​​​​​​​​​​​

长期坚持做有价值的事!积累沉淀,持续成长,升维思考!希望把编码作为长期兴趣爱好😄

目录

1. 安装最新版本release版本的golang

2. 安装最新版本protoc文件

3. 安装protoc-gen的插件

4. 配置系统环境变量

5. 编写proto文件

6.  执行命令,生成go的pb文件

7. 编写RPC的server和client

8.遇到问题


参考文章

gRPC使用参考:

Quick start | Go | gRPC

proto 3的语法参考:

https://developers.google.com/protocol-buffers/docs/proto3

protoc-gen-go插件参考:

https://developers.google.com/protocol-buffers/docs/reference/go-generated

1. 安装最新版本release版本的golang

这里我们直接到go官网下载最新版本的go,直接安装就可以,就不多做说明

2. 安装最新版本protoc文件

这里我们使用version 3的版本

下载protoc相应版本: Releases · protocolbuffers/protobuf · GitHub

这里我们下载Mac 64位版本:protoc-3.20.0-osx-x86_64.zip,并解压缩后放在~/Document/tools目录下,并修改文件名为protoc

安装参考文章:Protocol Buffer Compiler Installation | gRPC

3. 安装protoc-gen的插件

默认protoc不支持go,需要安装go的扩展插件

$ go install google.golang.org/protobuf/cmd/protoc-gen-go@latest 
$ go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest

切换到GOPATH的bin目录,可以看到安装的protoc-gen-go和protoc-gen-go-grpc两个应用

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAa2Vlbnc=,size_20,color_FFFFFF,t_70,g_se,x_16

查看一下版本

➜ bin ./protoc-gen-go --version 
protoc-gen-go v1.28.0 

➜ bin ./protoc-gen-go-grpc --version 
protoc-gen-go-grpc 1.2.0

4. 配置系统环境变量

配置protoc, protoc-gen-go和protoc-gen-go-grpc到系统的环境变量中

// 将protoc添加到环境变量 
export PATH=$PATH:/Users/xxx/Documents/tools/protoc/bin 
export PROTOC=/Users/xxx/Documents/tools/protoc/bin/protoc 
export PROTOC_INCLUDE=/Users/xxx/Documents/tools/protoc/include 
// 将GOPATH目录添加到环境变量,我们刚安装的protoc-gen存在该目录 
export PATH="$PATH:$(go env GOPATH)/bin"

直接在用户home目录执行

➜ ~ protoc-gen-go --version 
protoc-gen-go v1.28.0

这里可以看到已经添加成功了。下一步我们来写一个proto文件进行编译试试

5. 编写proto文件

syntax = "proto3"; 
option go_package = "gitee.com/CKeen/go-awesome/go-rpc/proto/hello"; 
option java_multiple_files = true; 
option java_package = "cn.ckeen"; 
option java_outer_classname = "Hello"; 

package hello; 

service Greeter { 
    rpc SayHello (HelloRequest) returns (HelloReply) {} 
} 

message HelloRequest { 
    string name = 1; 
} 

message HelloReply { 
    string message = 1; 
}

我们也可以从gRPC的官方demo拉取一个示例

git clone -b v1.45.0 --depth 1 https://github.com/grpc/grpc-go

6.  执行命令,生成go的pb文件

$ protoc --go_out=./ --go_opt=paths=source_relative \ 
    --go-grpc_out=./ --go-grpc_opt=paths=source_relative \ 
    proto/hello.proto

可以看到这里生成了两个hello.pb.go文件和hell_grpc.pb.go文件

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAa2Vlbnc=,size_20,color_FFFFFF,t_70,g_se,x_16

7. 编写RPC的server和client

server服务端代码

// server.go
import (
   "context"
   "flag"
   "fmt"
   "google.golang.org/grpc"
   pb "grpc/proto"
   "log"
   "net"
)



var (
   port = flag.Int("port", 50051, "The server port")
)


// server is used to implement helloworld.GreeterServer.
type server struct {
   pb.UnimplementedGreeterServer
}

// SayHello implements helloworld.GreeterServer
func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
   log.Printf("Received: %v", in.GetName())
   return &pb.HelloReply{Message: "Hello " + in.GetName()}, nil
}

func main() {
   flag.Parse()
   lis, err := net.Listen("tcp", fmt.Sprintf(":%d", *port))
   if err != nil {
      log.Fatalf("failed to listen: %v", err)
   }
   s := grpc.NewServer()
   pb.RegisterGreeterServer(s, &server{})
   log.Printf("server listening at %v", lis.Addr())
   if err := s.Serve(lis); err != nil {
      log.Fatalf("failed to serve: %v", err)
   }
}

客户端client端

// client.go
import (
   "context"
   "flag"
   "google.golang.org/grpc"
   "google.golang.org/grpc/credentials/insecure"
   pb "grpc/proto"
   "log"
   "time"
)

const (
   defaultName = "keen"
)


var (
   addr = flag.String("addr", "127.0.0.1:50051", "the address to connect to")
   name = flag.String("name", defaultName, "Name to greet")
)

func main() {
   flag.Parse()
   // 连接rpc服务
   conn, err := grpc.Dial(*addr, grpc.WithTransportCredentials(insecure.NewCredentials()))
   if err != nil {
      log.Fatalf("did not connect: %v", err)
   }
   defer conn.Close()
   c := pb.NewGreeterClient(conn)

   ctx, cancel := context.WithTimeout(context.Background(), time.Second)
   defer cancel()
   r, err := c.SayHello(ctx, &pb.HelloRequest{Name: *name})
   if err != nil {
      log.Fatalf("could not greet: %v", err)
   }
   log.Printf("Greeting: %s", r.GetMessage())
}

先将服务端启动,然后运行客户端,运行结果如下:

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAa2Vlbnc=,size_20,color_FFFFFF,t_70,g_se,x_16

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAa2Vlbnc=,size_20,color_FFFFFF,t_70,g_se,x_16

到这里一个rpc服务就可以跑起来了

8.遇到问题

1. mac下"无法验证开发者"

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAa2Vlbnc=,size_20,color_FFFFFF,t_70,g_se,x_16

解决办法: 点击屏幕左上角的苹果标志——系统偏好设置——安全性与隐私——通用

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿CKeen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值