转载

chuck-lua 一个lua网络应用框架

chuck是一个单线程,异步的C网络库.同时导出了lua接口,可以通过lua方便的编写网络应用.下面演示一下如何使用chuck编写一个简单的echo服务.

echo.lua

local chuck = require("chuck") local socket_helper = chuck.socket_helper local connection = chuck.connection local packet = chuck.packet local signal = chuck.signal local engine local function sigint_handler()  print("recv sigint")  engine:Stop() end local signaler = signal.signaler(signal.SIGINT) function on_new_client(fd)  print("on new client/n")  local conn = connection(fd,4096)  conn:Add2Engine(engine,function (_,p,err)   if p then    p = packet.clone(p)    print(p)    conn:Send(p,function (_)       print("packet send finish")       conn:Close()       conn = nil        end)   else    conn:Close()    conn = nil   end  end) end local fd =  socket_helper.socket(socket_helper.AF_INET,          socket_helper.SOCK_STREAM,          socket_helper.IPPROTO_TCP) socket_helper.addr_reuse(fd,1) local ip = "127.0.0.1" local port = 8010 if 0 == socket_helper.listen(fd,ip,port) then  print("server start",ip,port)  local server = chuck.acceptor(fd)  engine = chuck.engine()  server:Add2Engine(engine,on_new_client)  chuck.RegTimer(engine,1000,function() collectgarbage("collect") end)  signaler:Register(engine,sigint_handler)  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目前正在开发中,欢迎大家提出宝贵的意见.

https://github.com/sniperHW/chuck

正文到此结束
Loading...