skynet cjson
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
。
`