一、运行机制


1. 运行流程


在看完前面全部章节之后, 我们对cfadmin已经有了一个大致的了解. 现在我们来介绍一下他的执行流程!

当你在输入./cfadmin命令后, 并且按下回车键的那个瞬间. 框架就已经按照下面的流程开始运行了:

  1. 首先会检查你对默认参数的修改情况, 用于检查是否需要切换运行模式.

  2. 载入用户脚本入口文件(script/main.lua), 用于执行权交给开发者.

  3. 在用户脚本流程执行完毕后, 检查进程是否在执行完毕后退出.

  4. 启动了网络服务则需要继续注册与其相关的事件(信号、网络、定时器)等等.

  5. 将执行权交给调度器, 至此开始等待事件的来临.

    至此, 执行权将交给调度器来负责调度. 开发者也不再需要关心框架内部的执行流程, 仅需编写业务回调函数的逻辑即可.

  6. 当有用户访问来临的时候, 调度器会触发开发者编写的回调函数并开始执行开发者实现编写好的业务流程代码.

  7. 当开发者将业务流程处理完毕后, 需要返回合理的数据给到用户端予以展示.

    这样, 我们就完成了一次基本的交互流程.

2. 机制问题


这里有一点需要注意的是: "开发者在使用require导入文件的时候, 不可在文件方法函数之外执行异步代码."

这句话是什么意思呢? 例如, 当开发者使用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"

  local httpd = require "httpd"

  --[[
  ... do your want do
  ]]

这样你在运行后会得到一个:"attempt to yield from outside a coroutine"的错误提示, 而中文意思就是: "不能在非协程的环境下切换执行权".

这是因为require函数加载库的方式不支持yield函数! 所以当你直接进行初始化的时候, 框架内部会触发yield导致运行时抛出了异常.

那么正确的做法是什么呢? 我们来看下面这个示例:

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

local db = nil

local databases = {}

function databases.init(opt)
  db = DB:new(opt)
  db:connect()
end

function databases.query(query)
  return db:query(query)
end

function databases.self( ... )
  return db
end

return databases
-- main.lua
local mydb = require "mydb"
local db = mydb.init {
  host = "localhost",
  port = 3306,
  database = "cfadmin",
  charset = 'utf8'
  -- ...
}

local httpd = require "httpd"

-- [[
... do your want do
]]

这是用一种巧妙的functionupvalue的方式避开了require的限制, 合理的将执行权交还给框架. 这样就可以开始正确初始化了.

这仅限于依赖require执行某段异步代码块的时候, 不利于中大型项目代码的阅读. 希望项目管理人员尽量避免这样的设计.

二、搭建服务


框架内置的httpd库是基于HTTP/1.1协议开发的Web应用服务器, 内部的HTTP解析器可以高效的从纯文本中构建出HTTP Context对象.

下面我们将简单的介绍httpd库的几个常见的方法, 这样大家也能根据本章的示例快速上手写出简单的代码.

1. 导入httpd类


httpd库位于lualib下, 开发者可以内直接使用.

local httpd = require "httpd"

2. 创建httpd对象


开发者可以使用new方法创建一个httpd的app实例.

local app = httpd:new("app")

3. 注册静态文件路径


httpd提供给了内置的静态文件查找能力, 使用static方法注册静态文件路径即可.

app:static("static", 30)

4. 设置监听端口


httpd启动需要指定监听的端口, 默认监听所有网卡. 虽然没有使用第一个参数, 但是不可为空.

  app:listen("0.0.0.0", 8080)

5. 运行服务


在初始化完成后, app调用run方法将会启动httpd服务器. (run方法后面的代码可能永远不会有机会执行)

app:run()

(完整示例代码如下)

-- 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()

三、启动服务


按照上面的步骤编写完代码后, 我们可以运行根目录下的cfadmin可执行文件来启动我们的服务.

[candy@MacBookPro:~/cfadmin] $ ./cfadmin
[2020/09/05 13:31:23] [INFO] httpd listen: 0.0.0.0:8080
[2020/09/05 13:31:23] [INFO] httpd Web Server Running...

四、界面体验


现在, 让我们打开http://localhost:8080/index.html查看是否能正确显示页面了呢?

五、继续学习


本章节我们学会了如何大家httpd服务, 下一章节我们一起学习如何用注册路由处理函数.

Copyright © CandyMi 2019-2022 all right reserved,powered by Gitbook该文件修订时间: 2021-03-26 23:09:47

results matching ""

    No results matching ""