Lua Web快速開發指南(2) - cf的運行機制簡介與基於httpd庫的開發環境搭建

從本章開始假設你們都熟悉lua語法.html

運行流程

在上一章節學會了如何安裝cf後, 本章節就會介紹cf到運行機制與httpd的server搭建!git

cf是一個很是典型的基於協程的事件驅動開發框架在封裝成API後, 能夠依賴事件循環執行一套穩定運行時環境.github

而lua自己提供了強大的table數據結構能夠根據須要自行構建所謂的"config", 因此cf爲了減小無用的依賴就沒有提供額外的config文件進行配置.web

cf會假設全部業務代碼文件都在script目錄下, 因此建議您在script下自行劃分好文件的目錄歸屬.數據庫

cf將全部業務編寫的腳本目錄命名爲script, script目錄下點main.lua文件將會是入口文件. 這個main.lua執行完畢以後纔會真正進入事件循環.服務器

在執行完成script/main.lua文件後, cf則會是實際狀況決定是否須要開始運行事件循環. 假設開發者僅僅想運行print("hello world"), 那麼cf將會在main.lua執行完成後直接退出.數據結構

運行機制的問題與模塊化的設計

main.lua文件內部能夠導入其它lua代碼進行模塊化設計, 可是有一點須要注意的是: cf框架在使用require導入文件時, 導入的文件只能用於定義不可用於流程執行.app

什麼意思呢? 例如, 當你在使用建立一個httpd實例以前會先建立DB對象而且進行初始化! 這時候您能夠回設計像下面的代碼:框架

-- mydb.lua
local DB = require "DB"
local db = DB:new {
  host = "localhost",
  port = 3306,
  database = "cfadmin",
  charset = 'utf8'
  -- ...
}
local ok = db:connect()
if not ok then
  return nil
end
return db
-- main.lua
local db_cls = require "mydb"
--[[
... do your want do
]]

這樣作你會獲得一個錯誤提示:"attempt to yield from outside a coroutine", 這個錯誤提示的中文大概意思就是: "不能在非協程的環境下切換執行權".異步

這是由於require函數的對指定的腳本調用的Call方法使其不容許臨時切換出執行權, 而初始化數據庫鏈接操做是依賴cf的協程與異步操做因此就會致使上面的錯誤出現.

能夠將mydb.lua與main.lua的代碼替換成下面這樣(Cache庫同理)來解決:

-- mydb.lua
local DB = require "DB"

local db

return function ()
  if db then
    return db
  end
  db = DB:new {
    host = "localhost",
    port = 3306,
    database = "cfadmin",
    charset = 'utf8'
    -- ...
  }
  local ok = db:connect()
  if not ok then
    db:close()
    db = nil
    return nil, "鏈接失敗"
  end
  return db
end
-- main.lua
local get_db = require "mydb"
local db = get_db()
-- [[
... do your want do
]]

這是用一種巧妙的function與upvalue的方式避開了require的內部call調用, require返回後執行權從新回到了由cf啓動的協程中. 這樣就能夠開始正確初始化了.

這種狀況僅限於依賴require執行某段異步代碼塊的時候, 其它狀況下通常不會出現問題. 優質的項目管理人員通常不會出現這樣的設計.

使用httpd庫快速搭建lua web開發環境

httpd庫是cf內置的基於http 1.1協議開發的web server! 高效解析器是必不可少的, httpd庫使用picohttpparser解析器來構建http context.

咱們假設您至少看過httpd庫的API Reference, 而且至少知道下面所述的API.

此處全部的API與使用方式都將會在API Reference中找到.

1. 導入http庫

httpd庫位於app/lualib下, 使用者能夠在main.lua文件內直接使用local httpd = require "httpd"導入httpd庫.

2. 初始化一個httpd app對象

httpd庫使用lua class對象進行建立! 默認提供了new方法, 使用者可使用new方法建立一個httpd的app實例.

local httpd = require "httpd"

local app = httpd:new("app")

3. 註冊靜態文件路徑

httpd提供給了內置的靜態文件查找能力, 只須要使用者自動使用static方法註冊靜態文件路徑便可.

app:static("static", 30)

static表示使用者想將app/static文件夾當作靜態文件的根目錄.

4. 設置監聽端口

httpd啓動須要指定監聽的端口, 默認監聽全部網卡. 雖然沒有使用第一個參數, 可是不可爲空.

app:listen("0.0.0.0", 8080)

5. 運行

在初始化完成後, app調用run方法將會啓動httpd服務器. run方法後面的代碼可能永遠不會有機會執行.

app:run()

6. 運行cf

使用./cfadmin命令運行httpd server, 若是您看到相似運行等字樣說明httpd服務已經啓動完成, 不然將會有響應的錯誤提示.

7. 完整的代碼示例

-- script/main.lua
local httpd = require "httpd"
local app = httpd:new("app")

app:static("static", 30)

app:listen("0.0.0.0", 8080)

app:run()

體驗一下

如今, 讓咱們打開http://localhost:8080/index.html查看是否能正確顯示頁面了呢?

更多的httpd API

這裏你能夠找到更多有關httpd庫的API說明.

繼續學習

一下章咱們一塊兒學習如何用cf來註冊註冊路由

相關文章
相關標籤/搜索