开发者

golang中protobuf的使用详解

开发者 https://www.devze.com 2023-11-21 11:45 出处:网络 作者: 码说AI
目录前言1、protobuf配置2、proto文件处理3、使用前言 protobuf是Google公司提出的一种轻便高效的结构化数据存储格式,常用于结构化数据的序列化,具有语言无关、平台无关、可扩展性特性,常用于通讯协议、服务端数据
目录
  • 前言
  • 1、protobuf配置
  • 2、proto文件处理
  • 3、使用

前言

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文件

//指定版本
syntax = "proto3";
//包名
package pb;
//课程
message Course{
    int32 id = 1;
    string name = 2;
}
//学生
message Student{
    int32 id = 1;
    string name = 2;
    repeated Course courses = 3;
}

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

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

3、使用

package main
 
import (
    "fmt"
    "log"
    "test/protobuf/pb"
 
    "github.com/golang/protobuf/proto"
)
 
func main() {
    course1 := pb.Course{
        Id:   *proto.Int32(1),
        Name: *proto.String("Golang"),
    }
    course2 := pb.Course{
        Id:   *proto.Inhttp://www.devze.comt32http://www.devze.com(2),
        Name: *proto.String("python3"),
    }
    stu := pb.Student{
        Id:      *proto.Int32(1),
        Name:    *proto.String("笃志弘毅"),
        Courses: []*pb.Course{&course1, &course2},
    }
    //序列化
    data, err := proto.Marshal(&stu)
    if err != nil {
        log.Fatalln("proto.Marshal err:", err)
    }
    fmt.Println(data)
    //反序列化
    var stuNew pb.Student
    err = proto.Unmarshal(data, &stuNew)
    if err != nil {
        log.Fatalln("proto.Unmarshal err:", err)
    }
    fmt.Println(stuNew)
}

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

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

protoc-gen-go: unable to determine Go import path for "proto/ipc.proto"

 

Please specify either:

        • a "go_package" option in the .proto source file, or

        • a "M" argument on the command line.

 

See https://developers.google.com/protocol-buffers/docs/reference/go-generated#package for more information.

 

--go_out: protoc-gen-go: Plugin failed with status coandroidde 1.

源文件为:

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

编译命令为:

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";就可以解决了。

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

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

到此这篇关于golang中protobuf的使用详解的文章就介绍到这了,更多相关go protobuf内容请搜索编程客栈(www.devze.com)以前的文章或继续浏http://www.devze.com览下面的相关文章希望大家以后多多支持编程客栈(www.devze.com)!

0

精彩评论

暂无评论...
验证码 换一张
取 消