chuck-lua 一個lua網絡應用框架

jopen 9年前發布 | 19K 次閱讀 chuck-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 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!