最近在看RPC的相关的实现,其中google的 gRPC 默认使用 Protocol Buffers 来作为其接口描述语言(IDL,Interface Definition Language)以及使用 Protocol Buffers 实现消息的序列化与反序列化。因此,很有必要对 protocol buffers 作个初步的了解。
下文以 protobuf 来简称 protocol buffer。
安装
由于自己使用的是 Mac OS,因此,这里讲述 Mac OS 下如何安装 protobuf。
可以在以下链接下载最新版本的 protobuf ,下载链接。可以直接下载其源代码,然后进行编译安装。
源代码下载后,进入其目录,然后执行:
$ ./configure
$ make
$ make check
$ sudo make install
编译好后,使用以下命令来测试是否已成功安装:
$ protoc --version
libprotoc 3.2.0
说明已成功安装。
编写 .proto 文件
.proto
文件定义了消息的格式,一个常见的.proto
文件如下所示:
message Person {
required int32 id = 1;
required string name = 2;
optional string email = 3;
}
其中,关键字 required
表示这个字段是必须的,optional
表示这个字段是可选的。int32
表示这个字段是 32 位整型类型,string
表示这个字段是字符串类型。
编写完 .proto
文件后,使用 protoc
来编译。例如,将上面的消息格式保存为 person.proto
,进入这个文件所在的目录,执行以下命令:
protoc -I=. --python_out=. person.proto
这样,便在目录下生成 person_pb2.py
文件。 person_pb2.py
文件对 Person
类进行了定义。接下来,可以使用 Person
类提供的方法对来 Person
对象进行序列化和反序列化的操作。
序列化与反序列化
我们编写 test.py
来测试 protobuf 的使用。将上面生成的 person_pb2.py
文件拷贝到 test.py
文件所在的目录。
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import person_pb2
if __name__ == '__main__':
# 构造对象
person = person_pb2.Person()
person.id = 12345
person.name = 'leo'
person.email = 'haolee@live.com'
print person
print '********************'
# 序列化
serial_str = person.SerializeToString()
print serial_str
print '********************'
# 反序列化
person2 = person_pb2.Person().FromString(serial_str)
print person2.id, person2.name, person2.email
print '********************'
输出:
id: 12345
name: "leo"
email: "haolee@live.com"
********************
�`leohaolee@live.com
********************
12345 leo haolee@live.com
********************
参考资料
- https://github.com/google/protobuf/wiki
- https://github.com/google/protobuf
- https://github.com/google/protobuf/releases