本文介绍的关于protocol buffers的api是基于protoc-gen-lua
(see in github)这个项目的。
我的使用经验都是在开发Cocosd-x游戏的时候,lua脚本与服务器通信采用了protocol buffer
,协议编译工具正是protoc-gen-lua这个插件。插件的安装过程该项目的ReadMe已经描述的很清楚,这里主要总结一下实际使用中需要注意的问题,和编译生成的pb.lua
的常用API。
基本用法
1.定义一个.proto文件,假设叫做Test.proto
message Test { required int32 id = 1; optional string name = 2; repeated int32 ary = 3; message Foo { required int32 fid = 1; required string fname = 2; } repeated Foo foos = 4; }
2.使用protoc-gen-lua插件编译proto,生成Test_pb.lua
protoc --lua_out=./ Test.proto
3.在项目中require(“Test_pb”)
-- 如果require失败,请参考lua中`package.path`的使用 local pb =require("Test_pb") local test = pb.Test() test.id = 1 test.name = "hello" test.ary:append(1) -- 内置类型的repeated使用append() test.ary:append(2) local foo1 = pb.foos:add() -- 复合类型的repeated使用add() foo1.fid = 1 foo1.fname = "foo1" local foo2 = pb.foos:add() foo2.fid = 2 foo2.fname = "foo2" -- 序列化为字符串 local pb_data =test:SerializeToString() -- 从字符串解析 local recover = pb.Test() recover:ParseFromString(pb_data) print(recover.id, recover.foos[1].name, recover.foos[2].name)
常用API
在实际开发过程中,通信的数据都是放在pb里面的:
local pb = require("Test_pb")
如果在开发过程中,客户端和服务器是分开开发的,客户端在没有服务器给提供数据的情况下,通常要客户端自己造一些假数据来填充到界面。这些数据无非就是后端填充到pb里,然后发给前端。我们要自己造数据,就要知道怎么来操作pb。
pb是什么?
Test_pb.lua中是编译器自动生成的代码,主要是protocol的Descriptor对proto字段的翻译。它是一个table,它是一个message对象。
通过API来操纵pb
pb能调用哪些函数?
protoc-gen-lua的github仓库并没有说太多,只有一句:
“The API of this library is similar the protobuf library for python. For a more complete example, read the python documentation”
所以只能自己总结,参考着python版本的API来找。(通过protobuf.lua也能看到一些线索。)
图中红色框中的_AddXXXMethod就是在给pb对象添加API,那么XXX就是API的名字喽,如图黄色框所示。在代码里测试有时成功,有时报错。
这是因为,这些API是有使用条件的,比如上面第一节里,
repeated int32 ary = 3;
...
repeated Foo foos = 4;
同样是repeated类型的,添加元素,ary就得用append(), foos得用add().
下面就按照分类和限制条件总结一下,protobuf lua API的用法,也就是如何来操纵pb。