一、httpsrv 概述

httpsrv 是 Air8000 工业引擎提供的轻量级 HTTP 服务器实现,用于创建 Web 服务并处理 HTTP 请求。

其 HTTP 服务器功能主要包括:

  1. 基础 HTTP 服务器:创建 HTTP 服务、监听端口、处理请求和响应。
  2. 路由处理:支持不同 URI 路径的请求处理和路由分发。
  3. 静态文件服务:提供 HTML、CSS、JavaScript 等静态资源访问。
  4. 多网络模式支持:支持 WiFi AP、WiFi STA 和以太网 SPI 三种网络连接模式。
  5. 设备控制接口:提供 API 接口实现对设备功能的远程控制。

HTTP 服务器功能是 Air8000 工业引擎的重要扩展功能,通过它可以实现基于 Web 的设备配置、监控和控制,大大简化了设备的使用门槛和远程管理流程。

二、准备硬件环境

参考:Air8000 硬件环境清单,准备好硬件环境。

2.1 Air8000 整机开发板

本 demo 需要在 Air8000 开发板装上 WiFi 天线进行测试。

在这里插入图片描述

以太网环境需要连接网线,将网线的一头按下面的方式接入开发板,另一头接入路由器的 LAN 口,同时电脑也连接路由器的 LAN 口,即可正常进行测试。

在这里插入图片描述

三、准备软件环境

3.1 文章内容应用
  1. 烧录工具:Luatools 工具
  2. 本demo开发测试时使用的固件为LuatOS-SoC_V2012_Air8000_1.soc,本demo对固件版本没有什么特殊要求,所以你如果要测试本demo时,可以直接使用最新版本的内核固件;如果发现最新版本的内核固件测试有问题,可以使用我们开发本demo时使用的内核固件版本来对比测试;Air8000 烧录需要脚本文件:https://gitee.com/openLuat/LuatOS/tree/master/module/Air8000/demo/httpsrv
  3. LuatOS 运行所需要的 lib 文件:使用 Luatools 烧录时,勾选 添加默认 lib 选项,使用默认 lib 脚本文件。

准备好软件环境之后,接下来查看如何烧录项目文件到 Air8000 开发板中,将本篇文章中演示使用的项目文件烧录到 Air8000 开发板中。

3.2 API 介绍

这里仅介绍本篇文档所使用的 API,详情请查看:httpsrv 核心库wlan 核心库

httpsrv.start(port, callback, adapter)

启动 HTTP 服务器

wlan.init()

初始化 WiFi 模块

wlan.createAP(ssid, password)

创建 WiFi 热点

wlan.scan()

扫描周围 WiFi 网络

wlan.scanResult()

获取 WiFi 扫描结果

四、httpsrv 功能实现概述

本小节详细介绍 Air8000 开发板上 HTTP 服务器各种功能的实现方法和核心代码逻辑。

4.1 HTTP 服务器初始化和启动

HTTP 服务器初始化和启动功能用于创建和配置 HTTP 服务,设置请求处理函数。

4.1.1 功能定义

初始化 HTTP 服务器,配置监听端口和请求处理回调函数,选择网络适配器(AP、STA 或 ETH),然后启动服务开始监听 HTTP 请求。

4.1.2 代码示例
-- 检测当前使用的网卡适配器
local function get_current_adapter()
    -- 检查各个网卡是否就绪
    if netdrv and netdrv.ready(socket.LWIP_AP) then
        return socket.LWIP_AP, "AP"
    elseif netdrv and netdrv.ready(socket.LWIP_STA) then
        return socket.LWIP_STA, "STA"
    elseif netdrv and netdrv.ready(socket.LWIP_ETH) then
        return socket.LWIP_ETH, "ETH"
    end
end

local function start_http_server()
    -- 等待网络就绪事件
    sys.waitUntil("CREATE_OK")

    -- 获取当前使用的网卡适配器
    local adapter, adapter_name = get_current_adapter()
    local local_ip = socket.localIP(adapter)

    -- 启动HTTP服务器
    httpsrv.start(80, handle_http_request, adapter)
    log.info("HTTP", "文件服务器已启动,使用" .. adapter_name .. "模式")

    if adapter == socket.LWIP_AP then
        log.info("HTTP", "请连接WiFi: luatos8888 密码: 12345678")
    end

    log.info("HTTP", "访问地址: http://" .. (local_ip or "192.168.4.1"))
end

-- 启动HTTP服务器任务
sys.taskInit(start_http_server)

4.2 HTTP 请求处理

HTTP 请求处理功能用于接收和解析 HTTP 请求,并根据 URI 路径返回相应的响应。

4.2.1 功能定义

定义请求处理回调函数,根据不同的 URI 路径执行相应的处理逻辑,并返回状态码、响应头和响应体。

4.2.2 代码示例
local function handle_http_request(fd, method, uri, headers, body)
    log.info("httpsrv", method, uri, body or "")

    if uri == "/led/1" then
        LEDA(1)
        log.info("LED Control", "Turned ON")
        return 200, {}, "ok"
    elseif uri == "/led/0" then
        LEDA(0)
        log.info("LED Control", "Turned OFF")
        return 200, {}, "ok"
    elseif uri == "/send/text" then
        log.info("Text Request", "Method:", method, "Body Length:", body and #body or 0)
        if method == "POST" and body and #body > 0 then
            -- 直接打印接收到的文本内容
            log.info("Received Text:", body)
            return 200, {}, "ok"
        end
        return 400, {}, "Invalid request"
    elseif uri == "/scan/go" then
        wlan.scan()
        return 200, {}, "ok"
    elseif uri == "/scan/list" then
        return 200, {["Content-Type"]="application/json"}, (json.encode({data=scan_result, ok=true}))
    elseif uri == "/connect" then
        if method == "POST" and body and #body > 2 then
            local jdata = json.decode(body)
            if jdata and jdata.ssid then
                sys.timerStart(wlan.connect, 500, jdata.ssid, jdata.passwd)
                return 200, {}, "ok"
            end
        end
        return 400, {}, "ok"
    elseif uri == "/connok" then
        log.info("connok", json.encode({ip=socket.localIP(2)}))
        return 200, {["Content-Type"]="application/json"}, json.encode({ip=socket.localIP(2)})
    end
    return 404, {}, "Not Found" .. uri
end

4.3 LED 控制功能

LED 控制功能通过 HTTP API 接口实现对设备上 LED 灯的远程控制。

4.3.1 功能定义

初始化 LED 引脚,并提供 HTTP API 接口用于控制 LED 灯的开关状态。

4.3.2 代码示例
-- 初始化LED灯, 这里演示控制Air8000开发板绿灯,其他开发板请查看硬件原理图自行修改
local LEDA = gpio.setup(146, 0, gpio.PULLUP)

-- 在请求处理函数中的LED控制逻辑
if uri == "/led/1" then
    LEDA(1)
    log.info("LED Control", "Turned ON")
    return 200, {}, "ok"
elif uri == "/led/0" then
    LEDA(0)
    log.info("LED Control", "Turned OFF")
    return 200, {}, "ok"
end

4.4 文本发送功能

文本发送功能允许通过 Web 界面向设备发送文本数据,并在设备日志中显示。

4.4.1 功能定义

提供 POST 接口接收文本数据,将接收到的文本内容打印到设备日志中。

4.4.2 代码示例
-- 在请求处理函数中的文本发送逻辑
if uri == "/send/text" then
    log.info("Text Request", "Method:", method, "Body Length:", body and #body or 0)
    if method == "POST" and body and #body > 0 then
        -- 直接打印接收到的文本内容
        log.info("Received Text:", body)
        return 200, {}, "ok"
    end
    return 400, {}, "Invalid request"
end

4.5 WiFi 扫描功能

WiFi 扫描功能用于搜索周围可用的 WiFi 网络,并以 JSON 格式返回扫描结果。

4.5.1 功能定义

提供扫描接口启动 WiFi 扫描,提供结果获取接口返回扫描到的 WiFi 网络列表,并监听扫描完成事件。

4.5.2 代码示例
-- 在请求处理函数中的WiFi扫描控制逻辑
if uri == "/scan/go" then
    wlan.scan()
    return 200, {}, "ok"
elif uri == "/scan/list" then
    return 200, {["Content-Type"]="application/json"}, (json.encode({data=_G.scan_result, ok=true}))
end

-- WiFi扫描完成事件处理
local function scan_done_handle()
    local result = wlan.scanResult()
    _G.scan_result = {}
    for k, v in pairs(result) do
        log.info("scan", (v["ssid"] and #v["ssid"] > 0) and v["ssid"] or "[隐藏SSID]", v["rssi"], (v["bssid"]:toHex()))
        if v["ssid"] and #v["ssid"] > 0 then
            table.insert(_G.scan_result, {
                ssid = v["ssid"],
                rssi = v["rssi"]
            })
        end
    end
    log.info("scan", "aplist count:", #_G.scan_result)
end

-- 订阅WiFi扫描完成事件
sys.subscribe("WLAN_SCAN_DONE", scan_done_handle)

五、功能演示

5.1 HTTP 服务器启动

使用 Luatools 将代码烧录到 Air8000 开发板

烧录完毕后,日志中会打印网络初始化和 HTTP 服务器启动成功的信息

5.2 Web 控制界面访问

5.2.1 WiFi AP 模式

使用电脑或手机连接到 “luatos8888” WiFi 热点(密码:12345678)

在浏览器中输入服务器地址:http://192.168.4.1 进入 web 网页

5.2.2 WiFi STA 模式

首先需要在代码中将网卡设置为 WIFI STA 网卡

随后将 netdrv_wifi 中的 WiFi 改为自己的

随后烧录进开发板中,可以看到已经 Air8000 开发板已经连接上 WiFi

使用电脑或手机连接到与 Air8000 开发板相同的 WiFi 网络,然后在浏览器中输入 Air8000 获取到的 IP 地址,进入 web 网页

5.2.3 以太网 SPI 模式

首先需要在代码中将网卡设置为 以太网 网卡

随后烧录进开发板中,将电脑通过网线连接到同一局域网

然后在浏览器中输入 Air8000 获取到的 IP 地址,进入 web 网页

5.3 LED 控制功能演示

在 Web 界面中点击 “开启 LED” 按钮,系统会打开 LED 灯

在这里插入图片描述

点击 “关闭 LED” 按钮,系统将执行相反操作,LED 灯熄灭,状态区域显示 “LED 已关闭”

在这里插入图片描述

5.4 文本发送功能演示

在 Web 界面的文本输入框中输入文本

通过串口调试工具,可以在日志中看到接收到的文本内容

5.5 WiFi 扫描功能演示

在 Web 界面中点击 “扫描 WiFi 网络” 按钮

扫描完毕后,会在网页上显示出扫描到的 WIFI 信息

通过串口调试工具,可以在日志中看到扫描到的每个 WiFi 网络的详细信息

六、总结

HTTP 服务器功能为 Air8000 工业引擎提供了强大的 Web 交互能力,使用户可以通过浏览器方便地配置、监控和控制设备,大大提升了设备的易用性和可管理性。开发者可以基于本文档的示例,进一步扩展和定制 HTTP 服务器功能,实现更复杂的 Web 应用场景。

七、常见问题

7.1 无法连接到 WiFi 热点

问题:设备启动后,无法搜索到名为 “luatos8888” 的 WiFi 热点。

解决方案

  • 检查开发板的 WiFi 天线是否正确连接
  • 确认设备已成功启动,查看日志中是否有 WiFi 相关错误信息
  • 检查 WIFI 固件是否存在

7.2 无法访问 Web 界面

问题:已连接到 WiFi 热点,但无法访问 http://192.168.4.1

解决方案

  • 确认已正确连接到 “luatos8888” WiFi 热点
  • 查看设备日志,确认 HTTP 服务器是否成功启动
Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐