当前位置: 首页 > article >正文

记一次学习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,丹没毒放心食用 


http://www.kler.cn/a/502128.html

相关文章:

  • 如何将 sqlserver 数据迁移到 mysql
  • VS2015 + OpenCV + OnnxRuntime-Cpp + YOLOv8 部署
  • vue的KeepAlive应用(针对全部页面及单一页面进行缓存)
  • [ Spring ] Install MongoDB on Ubuntu24
  • nginx负载均衡-基于端口的负载均衡(一)
  • linux-28 文本管理(一)文本查看,cat,tac,more,less,head,tail
  • FreeSWITCH Sofia SIP 模块常用命令整理
  • 如何设计一个 RPC 框架?需要考虑哪些点?
  • 计算机网络 笔记 网络层1
  • 远程和本地文件的互相同步
  • 深度学习——pytorch基础入门
  • GPT 系列论文精读:从 GPT-1 到 GPT-4
  • 机器翻译优缺点
  • 2025第3周 | JavaScript中es7新增的特性
  • Kafka 超级简述
  • python中的if判断语句怎么写
  • 面向对象的基本概念
  • 如何选择 Dockerfile 的放置方式
  • Perl语言的语法
  • 【Git版本控制器--1】Git的基本操作--本地仓库
  • fastGpt 本地运行 mongo, 要加 directConnection=true 参数
  • 从电影《解密》,简单聊一聊现代密码学
  • Kubeflow:云原生机器学习工作流自动化开源框架详解
  • MySQL多版本并发(MVCC)机制
  • 阿里云ios镜像源
  • WPF中组件之间传递参数的方法研究