chuck-lua 一個lua網絡應用框架
原文:http://segmentfault.com/a/1190000002939797
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目前正在開發中,歡迎大家提出寶貴的意見.
項目主頁:http://www.baiduhome.net/lib/view/home/1435481683263</p> </strong>
本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!