1.引言
最近在学习skynet过程中发现在网络收发数据的过程中数据都是裸奔,就想加入一种数据序列化方式,json、xml简单好用,但我就是不想用,于是就想到了protobuf,对于protobuf C/C++的使用个人感觉有点重,正好在学Lua,就想着能不能通过Lua来处理这些业务逻辑,C/C++只负责底层功能,最开始是想自己通过C实现一个动态库给Lua调用,但是后来估算了一下工作量,怕自己走火入魔果断放弃,于是就去github寻找灵感,于是找到了lua-protobuf,OK有轮子了,不想再造了,直接用。
2.组织工程
现在来到第一步,创建echo工程。
mkdir echo && cd echo
第二步:拉取skynet项目到工作目录并构建。
git clone https://github.com/cloudwu/skynet.gitcd skynetgit submodule initgit submodule updatemake PLAT=linux
第三步:拉取lua-protobuf到工作目录并构建。
git clone https://github.com/starwing/lua-protobuf.gitcd lua-protobufmkdir build && cd buildcmake ..make
最后,这是我的现有工程结构,如下图。
OK,准备工作已经完毕,开始炼丹...
3.无内鬼可以炼丹
所有自己的Lua代码都会放在lua -src目录,现在基于skynet创建一个echo服务,代码如下
-- main.lua
local skynet = require "skynet"
local socket = require "skynet.socket"
local pb = require "pb"
local serpent = require "serpent"local function load_proto_file(filepath)pb.loadfile(filepath)
endlocal function sendto(clientfd, arg)socket.write(clientfd, arg)
endlocal function client_quit(clientfd)socket.close(clientfd)
endlocal function accept(clientfd, addr)socket.start(clientfd)local data = socket.read(clientfd)if not data thenclient_quit(clientfd)returnendlocal res = {token = "aaaaaaaaa"}-- 解码接收到的数据local dedata = pb.decode("Login.LoginRequest", data)print("recv : ", serpent.block(dedata))-- 将lua原表编码成protobuf的二进制数据local tmp = pb.encode("Login.LoginResponse", res) print("send : ", serpent.block(tmp))sendto(clientfd, tmp)socket.close(clientfd)
endlocal function main()-- 为了简单直接绝对路径写死load_proto_file("/home/oyj/game/echo/Login.pb")local listenfd = socket.listen("0.0.0.0", 8888)socket.start(listenfd, accept)
endskynet.start(main)
代码写完,开始写配置文件,在项目根目录写一个配置文件,如下:
thread=4
logger=nil
harbor=0
start="main"
-- 这里吧lua-protobuf的Lua文件路径告诉skynet
lua_path="./skynet/lualib/?.lua;./skynet/lualib/?/init.lua;./lualib/?.lua;./lua-protobuf/?.lua"
-- 我们下的lua代码在这里配置加载路径
luaservice="./skynet/service/?.lua;./lua-src/?.lua;"
lualoader="./skynet/lualib/loader.lua"
-- 配置lua-protobuf动态库的路径,让skynet可以加载到动态库
cpath="./skynet/cservice/?.so;./lua-protobuf/build/?.so"
lua_cpath="./skynet/luaclib/?.so;./lua-protobuf/build/?.so"
再写一个proto文件:
// Login.proto
syntax = "proto3";
package Login;message LoginRequest {string username = 1;string password = 2;
}message LoginResponse {string token = 1;
}
最后将proto文件生成Lua要的pb文件。
protoc -I . -o Login.pb Login.proto
最后找个之前客户端来测试,整体代码太多就不全部贴出来了,相信能看到这你是有点东西的,自己写应该简简单单,大概代码如下:
最最后目前的项目结构:
4.开始试丹
丹成!!!命令行进入工程根目录运行一下命令开始试丹!
./skynet/skynet config
skynet启动成功,效果如下:
发个数据测试一下:
client:
server:
OK,丹没毒放心食用