动手玩protocol buffers

我记得第一次编译thrift文件是运行一个脚本,可能是处于好奇心吧,看了看脚本里的内容,大概只有一行,但是是没有工程意识去认真研究。所以对rpc的认知,还是停留在纸面上。这种滞后持续了一年多,直到现在。所以是否动手有着截然不同的结果。
最近看了些protocol buffer的文章,要是以前定要跳过这些繁琐的细节,因为这是黑盒的。而现在我花时间去看看这个细节,更愿意动手来个quick start。
首先要安装,这个步骤我就费了好些周折,一开始安装的是最新版本,后来退回到了一个比较低的版本,不过这没有任何影响。

sudo apt-get install autoconf automake libtool  安装依赖,不可或缺

wget https://github.com/google/protobuf/archive/v2.6.1.zip

unzip v2.6.1.zip -d ./

cd protobuf-2.6.1

./autogen.sh

最后一个命令发生异常,原因是什么?怎么解决?

修改
curl http://googletest.googlecode.com/files/gtest-1.5.0.tar.bz2 | tar jx
mv gtest-1.5.0 gtest

wget https://github.com/google/googletest/archive/release-1.5.0.tar.gz
tar xzvf release-1.5.0.tar.gz
mv googletest-release-1.5.0 gtest

./configure
make
make check  (check结果可能会有错误,但不用管她,因为暂时那些功能用不到)
make install
protoc --version

执行最后一个命令报错。原因是什么?怎么解决?

protoc: error while loading shared libraries: libprotoc.so.8: cannot open shared
错误原因:
protobuf的默认安装路径是/usr/local/lib,而/usr/local/lib 不在Ubuntu体系默认的 LD_LIBRARY_PATH 里,所以就找不到该lib
解决方法:
1). 创建文件 /etc/ld.so.conf.d/libprotobuf.conf,在该文件中输入如下内容:
/usr/local/lib
2). 执行命令
sudo ldconfig

安装好了,然后使用:protoc --java_out=. xxx.proto,会生成Xxx.java
把这个java文件拷贝到工程里,发现报错,因为缺少依赖。

        <dependency>
            <groupId>com.google.protobuf</groupId>
            <artifactId>protobuf-java</artifactId>
            <version>2.6.1</version> 
        </dependency>

一定要注意版本,不然可能报错。

数据格式文件:rpc.proto

message Person {

    required int32 id = 1;

    required string name = 2;

    optional string email = 3;

    repeated string friends = 4;
}

测试代码:

// 按照定义的数据结构,创建一个Person
Rpc.Person.Builder personBuilder = Rpc.Person.newBuilder();
personBuilder.setId(1);
personBuilder.setName("叉叉哥");
personBuilder.setEmail("xxg@163.com");
personBuilder.addFriends("Friend A");
personBuilder.addFriends("Friend B");
Rpc.Person xxg = personBuilder.build();

// 将数据写到输出流,如网络输出流,这里就用ByteArrayOutputStream来代替
ByteArrayOutputStream output = new ByteArrayOutputStream();
xxg.writeTo(output);

// -------------- 分割线:上面是发送方,将数据序列化后发送 ---------------

byte[] byteArray = output.toByteArray();

// -------------- 分割线:下面是接收方,将数据接收后反序列化 ---------------

// 接收到流并读取,如网络输入流,这里用ByteArrayInputStream来代替
ByteArrayInputStream input = new ByteArrayInputStream(byteArray);


// 反序列化
Rpc.Person xxg2 = Rpc.Person.parseFrom(input);
System.out.println("ID:" + xxg2.getId());
System.out.println("name:" + xxg2.getName());
System.out.println("email:" + xxg2.getEmail());
System.out.println("friend:");
List<String> friends = xxg2.getFriendsList();
for(String friend : friends) {
    System.out.println(friend);
}

感谢:Java使用Protocol Buffers入门四步骤

推荐阅读更多精彩内容