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,丹沒毒放心食用?