Golang安装和使用protocol-buffer流程介绍
本篇文章向大家介绍《Golang安装和使用protocol-buffer流程介绍》,主要包括protocol-buffer、安装,具有一定的参考价值,需要的朋友可以参考一下。
安装protoc编译工具
首先安装protoc编译工具,在http://github.com/google/protobuf/releases,根据自己的系统选择包,下载后解压。我是win10 64,所以选择protoc-21.4-win64.zip,解压后放在了E盘。
添加环境变量,让系统命令可以识别protoc命令。
配置环境变量
PB_PATH=E:\protoc-3.21.4-win64
PATH=%PB_PATH%\bin
添加后,在命令行执行 protoc,返回信息,表示安装成功
编写proto文件
创建一个user.proto文件,该文件下可以定义一些user相关的需要加密的字段
//引入其他proto文件,就可以使用该文件中定义的message类型,定义本文件中的message下的字段
import "myproject/other_protos.proto";
// 指定的当前proto语法的版本
syntax = "proto3";
// 指定生成出来的文件的package,用来避免同一个文件调同名的消息时冲突
// 包说明符对生成代码的影响取决于您选择的语言,php会生成命名空间,go会生成package
package service;
//根据编程语言不同,参数名不同
//下面代码指定了生成go文件的生成目录,文件的包名。不设置包名时,包名默认为go文件所在目录名。会覆盖package设置的go的包名
//路径以执行命令的目录为当前目录,寻找相对路径
option go_package="./;service";
//定义消息类型,通过关键字message字段指定的,消息就是需要传输的数据格式的定义
message User {
// required必传;optional 可选;repeated 可重复初入。不写前缀默认为required
// 字段名后的数字不是默认值,是标识。标识号是[0,2^29-1]范围内的一个整数。[1-15]内的标识号在编码时只占用一个字节,包含标识符和字段类型,[16-2047]之间的标识符占用2个字节。建议为频繁出现的字段使用[1-15]间的标识符。
//字段类型除了除了常规类型,也可使用import引入文件中定义的message类型
required string sername = 1;
optional int32 age = 2;
repeated int32 height = 3;
}
//定义服务类型,用作rpc通讯
service SearchService {
//rpc 服务的函数名 (传入参数)返回(返回参数)
//传入和返回参数,需要使用proto中定义的message
rpc Search (SearchRequest) returns (SearchResponse);
}
生成指定语言的proto文件
protoc内置9中语言的编译插件,如下

我们以go为例。protoc没有内置go的编译器,需要引入外部插件protoc-gen-go
我们使用命令
go get github.com/golang/protobuf/protoc-gen-go
下载并编译了包,包中有main.go文件,所以在GOPATH/bin目录下生成了可执行文件protoc-gen-go.exe,这个文件就是我们在protoc中用到的插件
我们也可以自定义自己的插件。插件名必须以protoc-gen-插件名.exe命名
在调用时以:插件_out=参数 调用,之后回讲到如何制作插件
我们以go_out插件为例,执行命令
命令行后的第一个参数为输出目录。但是我们已经在go_package中指定了目录,所以第一个参数是无效的,填当前目录.即可。第二个参数是,要编译的文件路径和文件名(以命令执行目录为当前目录的相对路径)
protoc后可以追加1个或多个 -I=path 指定解析import指令时要在其中查找.proto文件的目录,若文件没有使用import,则不需要该参数
protoc --go_out=. proto_type/hello.proto
报错

protoc默认会从环境变量path下的路径中寻找插件,没找到报错。
查看发现path中只配置了go的安装GOROOT目录下的bin,而protoc-gen-go.exe在GOPATH的bin目录下
我们把protoc-gen-go.exe复制到GOROOT的bin目录下,即可。或者在环境变量path中添加gopath/bin目录。再次执行命令即可

调用proto
import (
"fmt"
"github.com/golang/protobuf/proto"
)
func main() {
//定义一个要加密的变量
msg := &protoc_type.User{
Username:"zhangsan",
Age:12,
}
//加密
marshal,err := proto.Marshal(msg)
if err!=nil{
fmt.Println(err.Error())
}else{
fmt.Println(marshal)
}
//定义一个变量,用于接收解码的值,类型必须用加密的值类型一样
unmarshal := &protoc_type.User{}
//解码
err2 := proto.Unmarshal(marshal,unmarshal)
if err2 == nil{
fmt.Println(unmarshal)
fmt.Println(unmarshal.Username)
fmt.Printf("%T",unmarshal)
}
}
制作插件
我们上文中提到,生成go用到了一个protoc的外部插件。插件的工作原理其实就是读取proto文件内容,并根据文件内容生成指定文件。文件中保存了定义的字段类型和方法之间的关系,以便编码和解码时使用
当我们在proto文件中定义了service,说明我们需要用到rpc服务。protoc内置的插件和一些官方的外部插件,只是提供了service中方法与参数类型的绑定,用于校验调用方法时类型是否正确。在service中定义的方法,我们需要自己创建。
当方法较多时,我们需要打开proto文件,一一对应的创建func,效率不高也容易出错。这种情况下,我们制作一个插件,读取service内容,自动创建方法,方法内的代码之后根据业务需求填充即可。
go官方提供了一个包,可以自动解析读取命令行传入proto文件,代码如下
package main
import (
"fmt"
"strings"
"google.golang.org/protobuf/compiler/protogen"
)
type rpc struct{}
func main() {
g := rpc{}
protogen.Options{}.Run(g.Generate)
}
// Generate generate service code
func (md *rpc) Generate(plugin *protogen.Plugin) error {
//遍历读取的命令行中传入的proto文件
for _, f := range plugin.Files {
//如果文件中没有定义service,跳过
if len(f.Services) == 0 {
continue
}
//根据proto文件名,生成一个自定义的文件,保存该proto中定义的func
fileName := f.GeneratedFilenamePrefix + ".svr.go"
//把该文件保存在proto文件的所在目录
t := plugin.NewGeneratedFile(fileName, f.GoImportPath)
//写入文字
t.P("// Code generated by protoc-gen-tinyrpc.")
//写入空行
t.P()
//写入包名
pkg := fmt.Sprintf("package %s", f.GoPackageName)
t.P(pkg)
t.P()
//遍历一个文件下所有service,自动生成方法
for _, s := range f.Services {
//插入注释,定义service类型
serviceCode := fmt.Sprintf(`%stype %s struct{}`,
getComments(s.Comments), s.Desc.Name())
t.P(serviceCode)
t.P()
//遍历一个service下的方法,生成方法
for _, m := range s.Methods {
funcCode := fmt.Sprintf(`%sfunc(this *%s) %s(args *%s,reply *%s)error{
// define your service ...
return nil
}
`, getComments(m.Comments), s.Desc.Name(),
m.Desc.Name(), m.Input.Desc.Name(), m.Output.Desc.Name())
t.P(funcCode)
}
}
}
return nil
}
// getComments get comment details
func getComments(comments protogen.CommentSet) string {
c := make([]string, 0)
c = append(c, strings.Split(string(comments.Leading), "\n")...)
c = append(c, strings.Split(string(comments.Trailing), "\n")...)
res := ""
for _, comment := range c {
if strings.TrimSpace(comment) == "" {
continue
}
res += "//" + comment + "\n"
}
return res
}
执行 go install 编译该文件,生成exe文件,文件名称设置为protoc-gen-gofunc.exe。然后再次执行protoc命令,如下
protoc --go_out=. proto_type/hello.proto --gofunc_out=. proto_type/hello.proto
执行后,会在proto_type目录下生成两个文件,hello.pd.go, hello.srv.go
文中关于golang的知识介绍,希望对你的学习有所帮助!若是受益匪浅,那就动动鼠标收藏这篇《Golang安装和使用protocol-buffer流程介绍》文章吧,也可关注golang学习网公众号了解相关技术文章。
Golang常用包使用介绍
- 上一篇
- Golang常用包使用介绍
- 下一篇
- Go+Redis实现延迟队列实操
-
- Golang · Go教程 | 17小时前 | 并发 · Go教程 · trace.NewTask go tool trace Go runtime/trace 执行跟踪 trace.WithRegion
- Go runtime/trace 怎样按任务标记跟踪区间
- 391浏览 收藏
-
- Golang · Go教程 | 18小时前 | flag · go · Go 命令行参数 flag.TextVar encoding.TextUnmarshaler
- Go flag.TextVar 怎样把自定义类型接入命令行
- 184浏览 收藏
-
- Golang · Go教程 | 19小时前 | 错误处理 · 模板 · Go教程 · html/template · 模板渲染 Go html/template missingkey 模板缺失字段 Execute错误
- Go html/template 缺失字段的严格渲染配置与错误处理
- 371浏览 收藏
-
- Golang · Go教程 | 19小时前 | html · go · 模板 · url · Go html/template 自动转义 URL上下文 template.URL
- Go html/template 怎样避免 URL 上下文误用
- 326浏览 收藏
-
- Golang · Go教程 | 19小时前 |
- Go text/template.ParseFS 怎样加载嵌入文件模板
- 208浏览 收藏
-
- Golang · Go教程 | 19小时前 |
- Go database/sql.NamedArg 怎样给 SQL 参数命名
- 311浏览 收藏
-
- Golang · Go教程 | 19小时前 | HTTP · go · Gin · Gin ShouldBindBodyWith 请求体重复绑定 ShouldBind binding.JSON
- Gin ShouldBindBodyWith 怎么让同一个请求体绑定两次
- 134浏览 收藏
-
- Golang · Go教程 | 20小时前 | go · 文件系统 · Go os.ReadDir Go File.ReadDir Go DirEntry Go 目录遍历
- Go os.ReadDir 怎样高效读取目录条目
- 269浏览 收藏
-
- Golang · Go教程 | 20小时前 | go · Go go/types.Config Go Importer Go 类型检查 types.Check
- Go go/types.Config 怎样给类型检查接入导入器
- 222浏览 收藏
-
- Golang · Go教程 | 20小时前 |
- Go maphash.Hash 怎样用固定种子复现哈希结果
- 341浏览 收藏
-
- Golang · Go教程 | 20小时前 | Go 字节切片 encoding/binary AppendByteOrder
- Go binary.ByteOrder.Append 怎样把整数追加到现有字节切片
- 373浏览 收藏
-
- Golang · Go教程 | 21小时前 | go · IPv6 Go ipv4 netip.ParsePrefix CIDR
- Go netip.ParsePrefix 怎样解析 CIDR 字符串
- 334浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 573次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 616次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 646次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 605次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 422次使用
-
- go日志库logrus的安装及快速使用
- 2022-12-25 358浏览
-
- Go语言集成开发环境IDE详细安装教程
- 2022-12-31 269浏览
-
- Go语言安装和GoLand2021最全超详细安装教程
- 2023-01-01 275浏览
-
- GO开发编辑器安装图文详解
- 2023-01-01 393浏览
-
- Golang学习笔记之安装Go1.15版本(win/linux/macos/docker安装)
- 2022-12-23 398浏览

