当前位置: 首页 > 工具软件 > go-gen > 使用案例 >

protoc protoc-gen-go protobuf 之间的关系

杨乐
2023-12-01

protoc protoc-gen-go protobuf 之间的关系

protobuf

protocol buffer 是谷歌内部的混合语言数据标准,通过将结构化的数据进行序列化,结果可用于通讯、存储. 该标准协议与语言无关、平台无关.
目前基本已被所有主流开发语言所支持. 其功能定位对标 jsonxml等数据标准.

  • 序列化:将数据结构或对象转换成二进制串的过程
  • 反序列化:将在序列化过程中所产生的二进制串转换成数据结构或对象的过程

项目地址https://github.com/google/protobuf.

protoc

protoc命令来自于https://github.com/google/protobuf 项目,它就是该项目提供的编译器.
可以将源文件xxx.proto编译成开发语言文件,例如xxx.pb.go,使之成为一个可以在go工程中直接使用的对象.
可以近似的理解为一个类似于自动生成代码的脚手架.

  1. 服务端定义一个数据结构,内容存储于foo.proto文件中.
  2. 如果我们的开发语言为java.依赖于protobuf项目提供的工具, 将foo.proto转化为foo.pb.java.
  3. 我们可以通过foo.pb.java中提供的api生成一个数据对象,该数据对象可以被java中的proto包识别.从而进行序列化,得到的结果可以用于存储或传输.
  4. 对端同样依赖于foo.proto,以及对端使用的开发语言.如果为golang. 那么依赖于foo.pb.go提供的api.从返序列化后的对象中提取数据.

protoc-gen-go

原生的protoc中并未支持自动生成go语言的代码.(太奇怪了,google作为go、protobuf的诞生地 竟然不支持go.)

root@MacBook-Pro bin % setopt no_nomatch  // 这一个命令是否执行 视情况而定
root@MacBook-Pro bin % protoc -h |grep out
...
--cpp_out=OUT_DIR           Generate C++ header and source.
--csharp_out=OUT_DIR        Generate C# source file.
--java_out=OUT_DIR          Generate Java source file.
--js_out=OUT_DIR            Generate JavaScript source.
--kotlin_out=OUT_DIR        Generate Kotlin file.
--objc_out=OUT_DIR          Generate Objective-C header and source.
--php_out=OUT_DIR           Generate PHP source file.
--python_out=OUT_DIR        Generate Python source file.
--ruby_out=OUT_DIR          Generate Ruby source file.

例如生成php版本的pb代码.

cd proto文件所在目录 && protoc --php_out=. *.proto

执行之后即可查看生成文件

幸运的是go代码的生成可以通过protoc的一个插件protoc-gen-go. 这也是一个命令.

protoc-gen-go的安装
1. go get -u -v github.com/golang/protobuf/protoc-gen-go
2. 将$GOPATH/bin 设置为环境变量,否则 protoc无法自动加载该插件

tips
如果已经安装过 go get -u github.com/golang/protobuf/protoc-gen-go@v1.1.0   走升级模式
如果未安装过   go get github.com/golang/protobuf/protoc-gen-go@v1.1.0      走安装模式

以上条件ok后,执行. 如果有报错 根据提示信息操作 一般不会有什么异常.

protoc --go_out=. task.proto

grpc 与 protoc-gen-go-grpc

grpc是一种rpc框架. 依赖于protobuf进行通讯. 所以学习grpc的时候,总也绕不过protocprotoc-gen-go.
如果我们仅仅使用 protoc-go-gen 产生的代码. 通常我们只能仅仅把把当做一个数据结构来使用.
而使用protoc-gen-go-grpc生成的go代码,里面会生成一些接入grpc框架相关代码,我们只要遵循这些要求进行实现,就可以利用grpc框架进行通讯.
当然,protoc-gen-go-grpc需要的proto文件也与单纯的proto文件略有区别

go get -u google.golang.org/grpc/cmd/protoc-gen-go-grpc  升级
go get google.golang.org/grpc/cmd/protoc-gen-go-grpc 安装

foo.proto

syntax="proto3";

package tsp.foo;

option go_package="./;foo_engine";

import "xxx.proto";

service FooEngineService {
    rpc Create(FooReqCreate) returns (FooResp);
    rpc Change(FooReqChange) returns (FooResp);
}

service FooEngineBusService {
    rpc CreateCallback(FooReqCreateCallback) returns (FooResp);
    rpc ChangeCallback(FooReqChangeCallback) returns (FooResp);
}

message FooResp {
    int32        Err    = 1;
    string       ErrMsg = 2;
    FooRespData  Data   = 3; 
}

编译

protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative *.proto    

我个人理解protoc-gen-go-grpcprotoc-go-gen是一个同等级插件.

巨人肩膀

  • protobuf介绍以及protoc安装 https://blog.csdn.net/love666666shen/article/details/89228450
  • proto-go-gen安装 https://www.cnblogs.com/mafeng/p/6781396.html
  • proto文件语法介绍 https://zhuanlan.zhihu.com/p/83010418
 类似资料: