美文网首页
skynet cjson

skynet cjson

作者: JunChow520 | 来源:发表于2021-06-16 22:50 被阅读0次

    Skynet早期拥有lua-cjson库,后被sproto取代。由于Lua5.3开始支持整形,但cjson并没有适配Lua5.3,若直接编译会造成JSON字符串中的数字转换为浮点数的问题。因此风云为cjson提供了一个补丁:https://github.com/mpx/lua-cjson/pull/22

    也可使用风云维护的另一个分支:https://github.com/cloudwu/lua-cjson

    cjson优缺点

    • 优点:速度快、支持UTF-8,没有依赖,MIT开源。
    • 缺点:不支持UTF-16、UTF-32

    失败操作

    查看Lua版本

    $ lua -v
    Lua 5.3.3  Copyright (C) 1994-2016 Lua.org, PUC-Rio
    

    下载代码

    $ git clone https://github.com/cloudwu/lua-cjson
    $ cd lua-cjson
    

    首先不要急着编译,查看lua-cjson目录下的Makefile文件中,对Lua版本的保存位置的要求。

    $ cat Makefile
    LUA_VERSION =       5.3
    TARGET =            cjson.so
    PREFIX =            /usr/local
    #CFLAGS =            -g -Wall -pedantic -fno-inline
    CFLAGS =            -O3 -Wall -pedantic -DNDEBUG
    CJSON_CFLAGS =      -fpic
    CJSON_LDFLAGS =     -shared
    LUA_INCLUDE_DIR =   $(PREFIX)/include
    LUA_CMODULE_DIR =   $(PREFIX)/lib/lua/$(LUA_VERSION)
    LUA_MODULE_DIR =    $(PREFIX)/share/lua/$(LUA_VERSION)
    LUA_BIN_DIR =       $(PREFIX)/bin
    

    需要配置Lua相关变量

    默认采用的是Lua5.3版本

    进入项目后编译生成动态库文件

    $ make
    

    编译成功后会在根目录下生成cjson.so动态库文件

    gcc -c -O3 -Wall -pedantic -DNDEBUG  -I/usr/local/include -fpic -o lua_cjson.o lua_cjson.c
    lua_cjson.c:43:10: fatal error: lua.h: No such file or directory
       43 | #include <lua.h>
          |          ^~~~~~~
    compilation terminated.
    make: *** [Makefile:93: lua_cjson.o] Error 1
    

    编译失败,问题出现在/usr/local/include目录下并没有lua.h头文件。

    编译安装Lua

    卸载使用apt安装的Lua

    切换至root用户

    $ sudo su root
    

    自动移除所有不使用的软件包

    $ apt autoremove
    

    移除软件包和配置文件

    $ apt-get purge lua5.3
    

    检测是否具有损坏的依赖

    $ apt-get check
    

    清理下载文件归档

    $ apt-get autoclean
    

    手工编译安装Lua,进入Ubuntu根目录下的opt目录下,使用wget工具远程下载Lua5.4.3源码包。

    $ cd /opt
    $ wget http://www.lua.org/ftp/lua-5.4.3.tar.gz
    $ tar -zxvf lua-5.4.3.tar.gz
    $ mv lua-5.4.3 lua
    

    编译Lua源文件

    $ cd lua
    $ make linux
    

    编译成功后,进入Lua的src目录,查看Lua版本。

    $ cd src
    $ ./lua -v
    Lua 5.4.3  Copyright (C) 1994-2021 Lua.org, PUC-Rio
    

    在Lua的src目录中会发现存在lua.h头文件。

    将编译好的Lua源码文件移动至/usr/local/src用户级源码目录下

    $ mv /opt/lua /usr/local/src/lua
    

    创建Lua的软连接,将其指向到/usr/bin目录下供管理员和一般用户使用。若已存在则先删除。

    $ rm -rf /usr/bin/lua
    $ ln -s /opt/lua/src/lua /usr/bin/lua
    $ lua -v
    Lua 5.4.3  Copyright (C) 1994-2021 Lua.org, PUC-Rio
    $ whereis lua
    lua: /usr/bin/lua
    

    安装lua-cjson

    远程下载lua-cjson到/usr/local/src目录下,解压后进入该目录。首先查看Makefile文件,修改其配置为当前安装的Lua位置。

    $ cd lua-cjson
    $ vim Makefile
    LUA_VERSION =       5.4
    TARGET =            cjson.so
    PREFIX =            /usr/local/src/lua/src/
    #CFLAGS =            -g -Wall -pedantic -fno-inline
    CFLAGS =            -O3 -Wall -pedantic -DNDEBUG
    CJSON_CFLAGS =      -fpic
    CJSON_LDFLAGS =     -shared
    LUA_INCLUDE_DIR =   $(PREFIX)
    LUA_CMODULE_DIR =   $(PREFIX)
    LUA_MODULE_DIR =    $(PREFIX)
    LUA_BIN_DIR =       $(PREFIX)
    

    然后在执行编译命令,即可成功生成cjson.so动态库文件。

    $ make
    

    将编译生成的cjson.so动态库文件复制到Skynet项目的luaclib文件夹内,即可使用cjson。

    $ cp cjson.so /mnt/d/
    

    使用

    Skynet中配置文件若采用JSON字符串,此时就需要JSON序列化和反序列化操作。

    例如:在项目的主配置文件中增加对MySQL主从配置,以JSON格式串作为配置。

    $ vim conf/config
    
    mysql_master = '{"host":"127.0.0.1", "port":3306, "user":"root", "password":"root", "database":"test"}'
    mysql_slave = '[{"host":"127.0.0.1", "port":3306, "user":"root", "password":"root", "database":"test"}]'
    

    在主入口服务脚本中读取JSON并反序列化

    $ vim service/main.lua
    
    local skynet = require "skynet"
    local cjson = require "cjson"
    
    skynet.start(function()
        skynet.error("skynet server start")
        -- 创建远程调试控制台服务
        local dcp = skynet.getenv("debug_console_port")
        if dcp then
            skynet.newservice("console")
            skynet.newservice("debug_console", "127.0.0.1", dcp)
        end
    
        -- 创建MySQL服务
        local mysql_master_config = cjson.decode(skynet.getenv("mysql_master"))
        local mysql_master = skynet.newservice("mysql", "master")
        skynet.call(mysql_master, "lua", "start", mysql_master_config, ".mysql_master")
    
        -- skynet.error(mysql_master_config)
    end)
    

    使用cjson.decode()函数从Skynet的环境配置中读取数据库配置并反序列化为table

    `

    相关文章

      网友评论

          本文标题:skynet cjson

          本文链接:https://www.haomeiwen.com/subject/uxxxyltx.html