1. 安装最新的protobuf
① 安装需要使用到的工具
- 安装之前,需要以下的工具
- 安装命令如下:
$ sudo apt-get install autoconf automake libtool curl make g++ unzip
② 编译安装probuf
- 我们不使用已经预编译好的release版本,而是直接通过git clone获取最新的源码,自己进行编译安装。
- 获取源代码:
$ git clone https://github.com/protocolbuffers/protobuf.git
$ cd protobuf
$ git submodule update --init --recursive
$ ./autogen.sh
- 开始编译源代码:
$ ./configure
$ make
$ make check
- 安装protobuf
$ sudo make install
$ sudo ldconfig
③ 检验protobuf安装是否成功
- 可以通过以下命令检查protobuf是否安装成功:
$ protoc -h
- 查看protobuf的版本
$ protoc --version
2. 安装go语言的插件
① 安装插件
- protobuf提供了很多语言,如C++、java、python、javaScript等,但是没有go的支持
- 因此,需要安装go语言的插件
- 先获取源码,注意: 下面的命令本来是最方便的方式,但是因为网络问题,无法连接!
$ go get -u github.com/golang/protobuf/proto
$ go get -v -u github.com/golang/protobuf/protoc-gen-go
- 解决办法: 通过
git clone
去下载,然后放到$GOPATH/src
对应的目录中。
git clone https://github.com/golang/protobuf.git
- 我最后将下载下来的包,放在了
$GOPATH/src/github.com/golang
目录下。
- 编译,获得可执行文件
$ cd $GOPATH/src/github.com/golang/protobuf/protoc-gen-go/
$ go build
- 将可执行文件移动到
$GOPATH/bin
目录下(手动完成的)
② 使用插件
- 先撰写一个叫service.proto的文件:
syntax = "proto3";
package protos;
message Tx {
bytes Data = 1;
uint64 Caller = 2;
}
message None {
}
service BlockChain {
rpc AddTx(Tx) returns (None){}
}
- 编译命令如下:
protoc --go_out=plugins=grpc:. *.proto
- 自动生成一个叫做service.pb.go的文件,内容如下(有省略):
// Code generated by protoc-gen-go. DO NOT EDIT.
// source: service.proto
package protos
import (
context "context"
fmt "fmt"
proto "github.com/golang/protobuf/proto"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
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 Tx struct {
Data []byte `protobuf:"bytes,1,opt,name=Data,proto3" json:"Data,omitempty"`
Caller uint64 `protobuf:"varint,2,opt,name=Caller,proto3" json:"Caller,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
...
func (m *Tx) GetData() []byte {
if m != nil {
return m.Data
}
return nil
}
func (m *Tx) GetCaller() uint64 {
if m != nil {
return m.Caller
}
return 0
}
.....
③ 使用service
- 为其定义接口:
type BlockChainClient interface {
AddTx(ctx context.Context, in *Tx, opts ...grpc.CallOption) (*None, error)
}
- 实现接口:
// AddTx will try to add a tx
func (chain *BlockChain) AddTx(ctx context.Context, in *pb.Tx) (*pb.None, error) {
err := chain.addTx(in.Data, in.Caller)
return &pb.None{}, err
}
- 调用接口,传入相关参数:
_, err := client.AddTx(context.Background(), &pb.Tx{
Data: NewTx(channelID, tx).Bytes(),
Caller:caller,
})
④ go install报错
- 自己的项目在进行go install 是报错了,根据错误信息来看,跟刚刚安装protobuf有关
building consensus raft...
# madledger/consensus/raft/protos
../consensus/raft/protos/service.pb.go:25:11: undefined: proto.ProtoPackageIsVersion3
building orderer...
# madledger/consensus/raft/protos
../consensus/raft/protos/service.pb.go:25:11: undefined: proto.ProtoPackageIsVersion3
building peer...
building client...
- 网上百度错误原因,大概意思就是
protoc-gen-go
的版本不正确,需要改为1.2.0版本。 - 参考undefined:proto.ProtoPackageIsVersion3博客,自己进行了一点改动,最后成功解决问题!
- 切换到v1.2.0版本
$ git -C "$(go env GOPATH)"/src/github.com/golang/protobuf checkout "v1.2.0"
2. 重新安装protoc-gen-go
$ cd ~/GOPATH/src/github.com/golang/protobuf
$ go install ./protoc-gen-go/
3. 成功解决问题,项目编译安装通过