一、搭建环境
参考: http://alilua.com/docs.html
下载和编译alilua
$ git clone https://github.com/oneoo/alilua.git
$ cd alilua
$ make
设定网站目录
这是调整后的目录,将alilua作为子工程放入工程目录。
project/
├── alilua/ # alilua源码目录
├── css/
├── js/
├── scripts/ # lua脚本目录
│ ├── index.lua
│ └── upload.lua
├── template/ # html模板目录
│ └── index.html
├── restart.sh # 快速重启脚本
├── route.lua # alilua路由脚本
├── host-route.lua # alilua路由配置
└── uploaddir/ # 上传文件目录
快速重启脚本(方便快速调试)
- 试过把cache关闭,但是没起到效果,所以就写了个脚本快速重启
- 启动alilua的命令:
./alilua process=4 bind=9999 daemon host-route=host-route.lua
- 关闭alilua的函数:
stop()
{
pid=`ps -ef| grep "alilua" | grep -v grep | awk '{print $2}' `
if [ "$pid"x != x ]; then
kill -9 $pid
echo "stop alilua"
fi
}
- 完整的restart.sh
二、快餐点餐工具需求
- 上传图片,支持多张
- 显示最新的菜单图片
- 显示点餐人名单,并载入已经点餐人的数据
- 提交订单(菜名和价格由点餐人输入)
- 基本的权限管理,可以防止误操作帮他人点餐或者修改别人的订单
- 该功能留到以后完善时做
三、开始编码
index.lua和模板的使用
- 参考:http://alilua.com/docs.html#模板引擎
- 就一句话加载index.html:
rts, err = dotemplate("/template/index.html")
- 这里说一下文件路径问题
- alilua中定义了一个
__root
变量保存主路径,而__root
来源于host-rote.lua
中配置host_route['*'] = '/home/hlm-devel/www/ordering/route.lua'
中route.lua
的父目录路径。 core.lua
中实现的函数参数涉及到文件时,都会加上__root
前缀,所以在使用这些函数的时候不需要自己添加__root
。
- alilua中定义了一个
index.html
我就用到了模板中的include命令用来包含header.html
和footer.html
使用jsonrpc实现api请求
- 最新版本的alilua中没有了文档中所说的
jsonrpc_handle
函数,而且get_post_body
函数的名字改成了get_request_body
。 - 通过查看老版本的alilua,我找出了
jsonrpc_handle
函数的实现,拷贝出来修改get_post_body
,在新版本中依然可以使用。 - 参考
http://alilua.com/docs.html#jsonrpc_handle
实现远程RPC
jsonrpc.js的实现
- 官网的客户端例子是使用jQuery实现的,小工具不想使用那么强大的库。
- 网上找了一堆一些纯js的实现,在github上看到jquery-jsonrpc的实现比较简单,因此参考这个库写了个纯js版本的jsonrpc库,已经上传到github了jsonrpc.js
MySQL数据库操作的封装(alilua的require和dofile)
- 单独建立
db.lua
文件封装用到的mysql操作 - 如果直接在
db.lua
中执行mysql
的connect
函数,不能使用require
包含文件,因为
因为 require 过程中产生的 Lua 运行环境不是一个协程,所以会报
attempt to yield across C-call boundary
错误。你把 require 改为 dofile 就可以运行的。
- 如果非要使用
require
,则需要在db.lua
里面把数据库操作封装成 function ,再给调用者使用。我用的是这种方式。
文件上传的实现
- 不想用 alilua 示例中那个 form 的例子的实现方式(标准的 html post 请求方式)
- 我采用 AJAX 实现 post 请求传文件内容, url 参数中传文件名的方式实现。
- AJAX 发送 post 请求遇到
sendAsBinary
函数在谷歌浏览器被移除的问题。- 谷歌一搜就有解答
if(!xhr.sendAsBinary){
xhr.sendAsBinary = function(datastr) {
function byteValue(x) {
return x.charCodeAt(0) & 0xff;
}
var ords = Array.prototype.map.call(datastr, byteValue);
var ui8a = new Uint8Array(ords);
this.send(ui8a.buffer);
}
}
- post 内容全部存放文件内容,所以一次 post 只发一个文件。
- 使用
read_request_body
循环读取 post 内容存入uploaddir
目录下面。
js实现下载csv数据
- 使用 html
<a
标签实现:<a href="data:text/csv;,xxxxxx"></a>
- 遇到编码问题
- alilua 全部使用UTF-8编码,发送到客户端的数据因此也是UTF-8的数据
- 使用 excel 打开UTF-8格式的 csv 文件会出现中文乱码,用 notepad++ 打开不乱码
- 在字符串前面添加 BOM 头也不管用,参考: Web 端 js 导出csv文件(使用a标签)
- 最后改用转成 gb2312 编码(只在客户端里面转码)搞定了,参考:unicode与GB2312的相互转换(js))
添加luapath到配置文件
- 参考
code-cache-ttl
的配置 - 在
host-route.lua
文件中添加luapath的配置:config['lua-path']='xxxx/?.lua;'
- 在
vhost.c
文件中添加全局变量lua_path:lua_path = get_string_in_table(L, "lua-path", &tl);
- 在
worker.c
中把lua_path
加入到package.path
中:sprintf(buf_4096 + epd->vhost_root_len + 1, "?.lua;%s/lua-libs/?.lua;%s", process_chdir, lua_path);
- 重新编译就搞定,已经修改好的代码在这里hanxi/alilua
源代码在这里:https://github.com/hanxi/alilua-demo-ordering
在此感谢alilua的作者oneoo在百忙之中抽空帮助我解答疑问