linux下安装和使用protoc

作者: 白云飞 分类: go 发布时间: 2019-04-08 10:21 阅读:

这两天看go的rpc,看到目前比较常用的rpc间通信的协议Protobuf。这种协议的优点很明显,比xml/json 的体积更小,更利于传输。但是缺点是,传输的报文,人工无法直接阅读。需要特定的工具来辅助序列化和反序列化。

Protobuf核心的工具集是C++语言开发的,在官方的protoc编译器中并不支持Go语言。因此,我们想要将 .proto 后缀的协议描述文件,生成对应的go代码的话,需要下载两个工具。

首先是安装官方的protoc工具,可以从 https://github.com/google/protobuf/releases下载,对应的工具包。由于我是 linux系统,当前我看到的最新版是 3.7.1 因此我下载 protoc-3.7.1-linux-x86_64.zip。这个版本的压缩包,解压好之后,我放在 

/home/nickbai/Downloads/protoc-3.7.1

此时,打开

vim /etc/profile

找到 PATH 项,追加如下的路径

/home/nickbai/Downloads/protoc-3.7.1/bin

并执行 ,刷新配置表命令

source /etc/profile

此时再执行 protoc –version,会得到如下的反馈

libprotoc 3.7.1

表示您已经安装成功了。接下来,我们安装针对Go语言的代码生成插件

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

执行完之后,会生成了一个 叫 protoc-gen-go 可执行文件,我为了方便,直接将其放到

/home/nickbai/Downloads/protoc-3.7.1/bin

目录下,这样 protoc-gen-go 也变成了一个全局的执行命令。之后,我们建立一个简单的  hello.proto

syntax = "proto3";

package main;

message String {
    string value = 1;
}

在 hello.proto 这个文件所在的目录执行

$ protoc --go_out=. hello.proto

便会生成了一个叫 hello.pb.go

// Code generated by protoc-gen-go. DO NOT EDIT.
// source: hello.proto

package main

import (
	fmt "fmt"
	proto "github.com/golang/protobuf/proto"
	math "math"
)

// Reference imports to suppress errors if they are not otherwise used.
var _ = proto.Marshal
var _ = fmt.Errorf
var _ = math.Inf

// This is a compile-time assertion to ensure that this generated file
// is compatible with the proto package it is being compiled against.
// A compilation error at this line likely means your copy of the
// proto package needs to be updated.
const _ = proto.ProtoPackageIsVersion3 // please upgrade the proto package

type String struct {
	Value                string   `protobuf:"bytes,1,opt,name=value,proto3" json:"value,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (m *String) Reset()         { *m = String{} }
func (m *String) String() string { return proto.CompactTextString(m) }
func (*String) ProtoMessage()    {}
func (*String) Descriptor() ([]byte, []int) {
	return fileDescriptor_61ef911816e0a8ce, []int{0}
}

func (m *String) XXX_Unmarshal(b []byte) error {
	return xxx_messageInfo_String.Unmarshal(m, b)
}
func (m *String) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) {
	return xxx_messageInfo_String.Marshal(b, m, deterministic)
}
func (m *String) XXX_Merge(src proto.Message) {
	xxx_messageInfo_String.Merge(m, src)
}
func (m *String) XXX_Size() int {
	return xxx_messageInfo_String.Size(m)
}
func (m *String) XXX_DiscardUnknown() {
	xxx_messageInfo_String.DiscardUnknown(m)
}

var xxx_messageInfo_String proto.InternalMessageInfo

func (m *String) GetValue() string {
	if m != nil {
		return m.Value
	}
	return ""
}

func init() {
	proto.RegisterType((*String)(nil), "main.String")
}

func init() { proto.RegisterFile("hello.proto", fileDescriptor_61ef911816e0a8ce) }

var fileDescriptor_61ef911816e0a8ce = []byte{
	// 76 bytes of a gzipped FileDescriptorProto
	0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe2, 0xe2, 0xce, 0x48, 0xcd, 0xc9,
	0xc9, 0xd7, 0x2b, 0x28, 0xca, 0x2f, 0xc9, 0x17, 0x62, 0xc9, 0x4d, 0xcc, 0xcc, 0x53, 0x92, 0xe3,
	0x62, 0x0b, 0x2e, 0x29, 0xca, 0xcc, 0x4b, 0x17, 0x12, 0xe1, 0x62, 0x2d, 0x4b, 0xcc, 0x29, 0x4d,
	0x95, 0x60, 0x54, 0x60, 0xd4, 0xe0, 0x0c, 0x82, 0x70, 0x92, 0xd8, 0xc0, 0x8a, 0x8d, 0x01, 0x01,
	0x00, 0x00, 0xff, 0xff, 0xb2, 0x47, 0x15, 0x9d, 0x3b, 0x00, 0x00, 0x00,
}

至此,就可以快乐的研究下去了。

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!