Skynet | lua-protobuf
概述
在最新的skynet中我使用的是云风的pbc库来解析protobuf,该项目中的一个文件protobuf.lua 使用了module语法在lua5.1版本中已经删除,最新的skynet是lua5.4版本,于是我找到了解析protobuf的lua库–lua-protobuf。在最新的skynet中,集成lua-protobuf
所需环境如下:
- skynet- lua5.4
- luarocks
- lua-protobuf: https://github.com/starwing/lua-protobuf
- ubuntu16.04
Install skynet & luarocks & lua-protobuf
编译安装skynet
$ git clone https://github.com.cnpmjs.org/cloudwu/skynet.git
$ cd skynet && make linux
编译安装luarocks
$ wget https://luarocks.github.io/luarocks/releases/luarocks-3.5.0.tar.gz
$ tar -zxvf luarocks-3.5.0.tar.gz
$ cd luarocks-3.5.0
$ ./configure --prefix=/usr/local/luarocks --with-lua-bin=/aseit-data/work_zhang/cppCode/lastBattle_skynet/skynet/3rd/lua --with-lua-include=/aseit-data/work_zhang/cppCode/lastBattle_skynet/skynet/3rd/lua
--prefix
设置Luarocks
安装路径,--with-lua-bin
指定Luarocks
依赖的 Lua 路径。--with-lua-bin
和--with-lua-include
这两个参数指定的是skynet项目中所使用的lua5.4库路径。
编译安装lua-protobuf
$ git clone https://github.com.cnpmjs.org/starwing/lua-protobuf.git && cd lua-protobuf
$ luarocks make rockspecs/lua-protobuf-scm-1.rockspec
在skynet中使用lua-protobuf
lua-protobuf
编译成功的话,将pb.so
放在config文件中lua_cpath
项配置的目录下面,同时将protoc.lua
放在config文件lua_path
配置的目录下,就可以调用protoc
中的库方法。我当前项目这两项的配置如下:
lua_path = root.."lualib/?.lua;"..root.."lualib/?/init.lua"
lua_cpath = root .. "luaclib/?.so"
官方的例子是直接使用protoc加载一个protobuf。我们一般使用protobuf是先写.proto
文件,然后用protoc
命令生成.pb
文件,然后在项目中使用 .pb
文件
示例GCToLS.proto
:
syntax = "proto3";
package GCToLS;
enum MsgID
{
eMsgToLSFromGC_Begin1 = 0;
eMsgToLSFromGC_Begin = 1;
eMsgToLSFromGC_AskLogin = 2;
eMsgToLSFromGC_End = 3;
}
message AskLogin
{
MsgID msgid = 1;
uint32 platform = 2;
string uin = 3;
string Sessionid = 4;
}
使用protoc
命令编译成.pb
文件
sudo protoc --descriptor_set_out ./pbs/gctols.pb ./ProtoFile/GCToLS.proto
语法格式 protoc –descriptor_set_out 输出 输入
在skynet项目中使用lua-protobuf
.
1.载入gctols.pb文件
local pb = require "pb"
assert(pb.loadfile "./protos/pbs/gctols.pb")
2.获取enum类型
pb.enum("GCToLS.MsgID", "eMsgToLSFromGC_AskLogin")
3.编解码数据
function gctols.encode(asklogin)
return assert(pb.encode("GCToLS.AskLogin", asklogin))
end
function gctols.decode(asklogin)
return assert(pb.decode("GCToLS.AskLogin",asklogin))
end
完整示例:
//gctols.lua
local pb = require "pb"
assert(pb.loadfile "./protos/pbs/gctols.pb") -- 载入刚才编译的pb文件
local gctols = {<!-- -->}
function gctols.msgid()
return pb.enum("GCToLS.MsgID", "eMsgToLSFromGC_AskLogin")
end
function gctols.type(type)
return pb.enum("GCToLS.MsgID", type)
end
function gctols.encode(asklogin)
return assert(pb.encode("GCToLS.AskLogin", asklogin))
end
function gctols.decode(asklogin)
return assert(pb.decode("GCToLS.AskLogin",asklogin))
end
return gctols
test.lua
local gctols = require "gctols"
local asklogin = {
msgid = "eMsgToLSFromGC_AskLogin",
platform = 1,
uin = "1",
Sessionid = "1"
}
local encodedata = gctols.encode(asklogin)
local decodedata = gctols.decode(encodedata)
这里要注意的是,.proto
文件中成员变量区分大小写,在解码得到的table
数据,在获取对应的key数据时需要大小写对应。在编码table
数据时,对应的key
也要大小对应,不然编码不通过。比如上面的Sessionid
这个key
。
使用lua-protobuf的细节请参考官方github:
--完--
- 原文作者: 留白
- 原文链接: https://zfunnily.github.io/2021/01/skynetprotobuf/
- 更新时间:2024-04-16 01:01:05
- 本文声明:转载请标记原文作者及链接