自学内容网 自学内容网

记一次学习skynet中的C/Lua接口编程解析protobuf过程

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.git

cd skynet

git submodule init

git submodule update

make PLAT=linux

        第三步:拉取lua-protobuf到工作目录并构建。

git clone https://github.com/starwing/lua-protobuf.git

cd lua-protobuf

mkdir build && cd build

cmake ..

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)
end

local function sendto(clientfd, arg)
    socket.write(clientfd, arg)
end

local function client_quit(clientfd)
    socket.close(clientfd)
end

local function accept(clientfd, addr)
    socket.start(clientfd)
    local data = socket.read(clientfd)
    if not data then
        client_quit(clientfd)
        return
    end

    local 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)
end

local function main()
    -- 为了简单直接绝对路径写死
    load_proto_file("/home/oyj/game/echo/Login.pb")
    local listenfd = socket.listen("0.0.0.0", 8888)
    socket.start(listenfd, accept)
end

skynet.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,丹没毒放心食用 


原文地址:https://blog.csdn.net/weixin_55951019/article/details/145093889

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!