chuck是一个单线程,异步的C网络库.同时导出了lua接口,可以通过lua方便的编写网络应用.
下面演示一下如何使用chuck编写一个简单的echo服务.
echo.lua
local chuck = require("chuck")
local socket = require("distri.socket")
local engine = require("distri.engine")
local signal = chuck.signal
local signaler = signal.signaler(signal.SIGINT)
local clone = chuck.packet
local server = socket.stream.listen("127.0.0.1",8010,function (s,errno)
if s then
if s:Ok(4096,socket.stream.rawdecoder,function (_,msg,errno)
if msg then
s:Send(clone(msg))
else
s:Close()
s = nil
end
end) then
s:SetRecvTimeout(5000)
end
end
end)
if server then
signaler:Register(engine,function ()
engine:Stop()
end)
chuck.RegTimer(engine,1000,function()
collectgarbage("collect")
end)
engine:Run()
end
在命令行下输入./lua echo.lua,然后通过telnet连接服务器即可.
chuck提供了面向事件回调的接口,接下来将会使用lua coroutine中对基本的chuck接口进行封装,实现一个同步网络应用开发框架.
下面再看一个http server的示例.
http.lua
local chuck = require("chuck")
local Http = require("samples.lua.http.http")
local signaler = chuck.signal.signaler(chuck.signal.SIGINT)
signaler:Register(Http.engine,function ()
print("recv sigint")
Http.Stop()
end)
local server = Http.HttpServer(function (req,res)
res:WriteHead(200,"OK", {"Content-Type: text/plain"})
res:End("hello world!")
end):Listen("127.0.0.1",8010)
if server then
Http.Run()
end
我最终希望将chuck变成一个可以使用lua来编写的应用服务器框架,下面是结合使用luasql生成动态页面的示例.
mysql.html
<!DOCTYPE html><!--STATUS OK-->
<html>
<head>
</head>
<?lua
local str = [[
<table border="1">]]
local driver = require "luasql.mysql"
env = driver.mysql()
conn = env:connect("ias_test","root","802802","127.0.0.1",3306)
conn:execute"SET NAMES GB2312"
cur = conn:execute("select id,UserName from user limit 20")
row = cur:fetch("a")
str = str .. [[
<tr>
<td>id</td>
<td>name</td>
</tr>]]
while row do
str = str .. "<tr><td>" .. row.id .. "</td><td>" .. row.UserName .. "</td></tr>"
row = cur:fetch("a")
end
str = str .. "</table>
"
conn:close()
env:close()
return str
/?lua>
</html>
这个html文件中通过使用<?lua>
标签嵌入了一段lua脚本,当请求这个页面的时候,内嵌的lua脚本将会被执行以生成输出页面.
为了让这个html中的lua脚本得以正确执行,http.lua将被调整成如下形式:
local chuck = require("chuck")
local Http = require("samples.lua.http.http")
local signaler = chuck.signal.signaler(chuck.signal.SIGINT)
local Template = require("samples.lua.http.Template")
signaler:Register(Http.engine,function ()
print("recv sigint")
Http.Stop()
end)
--dynamic page
local server = Http.HttpServer(function (req,res)
res:WriteHead(200,"OK", {"Content-Type: text/html"})
res:End(Template.Load("samples/lua/http/index.html"))
end):Listen("127.0.0.1",8010)
if server then
Http.Run()
end
chuck目前正在开发中,欢迎大家提出宝贵的意见.