• golang——win10环境protobuf的使用


    protobuf是Google公司提出的一种轻便高效的结构化数据存储格式,常用于结构化数据的序列化,具有语言无关、平台无关、可扩展性特性,常用于通讯协议、服务端数据交换场景。

    protobuf的核心内容包括:

    • 定义消息:消息的结构体,以message标识。
    • 定义接口:接口路径和参数,以service标识。

    通过protobuf提供的机制,服务端与服务端之间只需要关注接口方法名(service)和参数(message)即可通信,而不需关注繁琐的链路协议和字段解析,极大降低了服务端的设计开发成本。

    1、protobuf配置

    (1)https://github.com/protocolbuffers/protobuf/releases

    (2)选择适合的版本:protoc-3.8.0-win64.zip

    (3)解压后将文件 protoc.exe 所在目录添加到环境变量 Path

    (4)检查protobuf版本,CMD命令窗口执行:protoc --version

    2、proto文件处理

    (1)获取相关库

    go get -u github.com/golang/protobuf/protoc-gen-go

    (2)编写test.proto文件

    1. //指定版本
    2. syntax = "proto3";
    3. //包名
    4. package pb;
    5. //课程
    6. message Course{
    7.     int32 id = 1;
    8.     string name = 2;
    9. }
    10. //学生
    11. message Student{
    12.     int32 id = 1;
    13.     string name = 2;
    14.     repeated Course courses = 3;
    15. }

    (3)生成文件命令:protoc --go_out=. test.proto

    命令执行完,会在test.proto同级目录下生成test.pb.go文件

    3、使用

    1. package main
    2. import (
    3. "fmt"
    4. "log"
    5. "test/protobuf/pb"
    6. "github.com/golang/protobuf/proto"
    7. )
    8. func main() {
    9. course1 := pb.Course{
    10. Id: *proto.Int32(1),
    11. Name: *proto.String("Golang"),
    12. }
    13. course2 := pb.Course{
    14. Id: *proto.Int32(2),
    15. Name: *proto.String("Python3"),
    16. }
    17. stu := pb.Student{
    18. Id: *proto.Int32(1),
    19. Name: *proto.String("笃志弘毅"),
    20. Courses: []*pb.Course{&course1, &course2},
    21. }
    22. //序列化
    23. data, err := proto.Marshal(&stu)
    24. if err != nil {
    25. log.Fatalln("proto.Marshal err:", err)
    26. }
    27. fmt.Println(data)
    28. //反序列化
    29. var stuNew pb.Student
    30. err = proto.Unmarshal(data, &stuNew)
    31. if err != nil {
    32. log.Fatalln("proto.Unmarshal err:", err)
    33. }
    34. fmt.Println(stuNew)
    35. }

    问题解决:编译go版本proto3出现"go_package"错误

    在使用protobuf2升到protobuf3时,更新了proto-gen-go,编译proto文件进报了错误

    1. protoc-gen-go: unable to determine Go import path for "proto/ipc.proto"
    2. Please specify either:
    3. • a "go_package" option in the .proto source file, or
    4. • a "M" argument on the command line.
    5. See https://developers.google.com/protocol-buffers/docs/reference/go-generated#package for more information.
    6. --go_out: protoc-gen-go: Plugin failed with status code 1.

    源文件为:

    1. syntax = "proto3";
    2. package ipc;
    3. // 长连接Token验证请求
    4. message GameAuthReq {
    5. string authToken = 1; // Token
    6. string serverId = 2; // 登录服务器ID
    7. }
    8. ...

    编译命令为:

    protoc --go_out=. proto/ipc.proto
    
    • protoc-gen-go v1.27.1
    • protoc v3.12.3

    原因是protoc-gen-go版本过高,对源proto文件需要添加包名。在proto文件中添加option go_package = "/ipc";就可以解决了。

    1. syntax = "proto3";
    2. package ipc;
    3. option go_package = "/ipc";
    4. // 长连接Token验证请求
    5. message GameAuthReq {
    6. string authToken = 1; // Token
    7. string serverId = 2; // 登录服务器ID
    8. }
    9. ...

    还有一种解决办法就是把protoc-gen-go版本退回到1.3.2及以下也可以解决。

  • 相关阅读:
    elastic数据迁移或者修改mapping
    【康师傅】MySQL事务
    Redis(二)-基本数据类型的使用
    R语言ggplot2可视化:使用ggpubr包的ggtexttable函数可视化表格数据(直接绘制表格图或者在图像中添加表格数据)
    81 # 多语言
    Java后端开发——实现登录验证程序
    2022年高教社杯全国大学生数学建模竞赛-A题:波浪能最大输出功率设计(附MATLAB代码)
    如何在Centos8中添加附加的IP
    纸条解密-栈的应用
    HTML5期末大作业:基于html企业官网项目的设计与实现【艺术官网】
  • 原文地址:https://blog.csdn.net/waysoflife/article/details/133929407