init: Air780EPM 官方 LuatOS 项目代码基线
- 来源: 合宙 LuatOS 官方仓库 air780epm 模块完整代码 - 路径: luatos/air780epm/module/Air780EPM/demo 含官方 demo(含 mqtt/mqtts/socket/uart 等) - 后续: 基于 demo 开发 UART<->MQTT 数据上报功能
This commit is contained in:
@@ -0,0 +1,304 @@
|
||||
--[[
|
||||
@module httpplus
|
||||
@summary httpplus应用功能模块
|
||||
@version 1.0
|
||||
@date 2025.08.06
|
||||
@author 马梦阳
|
||||
@usage
|
||||
本文件为httpplus应用功能模块,核心业务逻辑为:基于不同的应用场景,演示httpplus扩展库的使用方式;
|
||||
http核心库和httpplus扩展库的区别如下:
|
||||
| 区别项 | http核心库 | httpplus扩展库 |
|
||||
| --------------------------------- | ------------------------------------------------------------------------- | ---------------------------- |
|
||||
| 文件上传 | 文件最大64KB | 只要内存够用,文件大小不限 |
|
||||
| 文件下载 | 支持,只要文件系统空间够用,文件大小不限 | 不支持 |
|
||||
| http header的key: value的限制 | 所有header的value总长度不能超过4KB,单个header的value长度不能超过1KB | 只要内存够用,header长度不限 |
|
||||
| 鉴权URL自动识别 | 不支持 | 支持 |
|
||||
| 接收到的body数据存储支持zbuff | 不支持 | 支持,可以直接传输给uart等库 |
|
||||
| 接收到的body数据存储到内存中 | 最大支持32KB | 只要内存够用,大小不限 |
|
||||
| chunk编码 | 支持 | 不支持 |
|
||||
|
||||
|
||||
本文件没有对外接口,直接在main.lua中require "httpplus_app"就可以加载运行;
|
||||
]]
|
||||
|
||||
|
||||
|
||||
local httpplus = require "httpplus"
|
||||
|
||||
|
||||
-- 普通的http get请求功能演示
|
||||
-- 请求的body数据保存到内存变量中,在内存够用的情况下,长度不限
|
||||
-- timeout可以设置超时时间
|
||||
local function httpplus_app_get()
|
||||
local body
|
||||
-- https get请求https://httpbin.luatos.com/get网页内容
|
||||
-- 如果请求成功,请求的数据保存到response.body中
|
||||
local code, response = httpplus.request({url="https://httpbin.luatos.com/get"})
|
||||
log.info("httpplus_app_get1", code==200 and "success" or "error", code)
|
||||
if code==200 then
|
||||
log.info("httpplus_app_get1 headers", json.encode(response.headers or {}))
|
||||
body = response.body:query()
|
||||
log.info("httpplus_app_get1 body", body and (body:len()>512 and body:len() or body) or "nil")
|
||||
end
|
||||
|
||||
|
||||
-- http get请求http://httpbin.luatos.com/get网页内容,超时时间为3秒
|
||||
-- 请求超时时间为3秒,用户自己写代码时,不要照抄3秒,根据自己业务逻辑的需要设置合适的超时时间
|
||||
-- 如果请求成功,请求的数据保存到body中
|
||||
code, response = httpplus.request({url="http://httpbin.luatos.com/get", timeout=3})
|
||||
log.info("httpplus_app_get2", code==200 and "success" or "error", code)
|
||||
if code==200 then
|
||||
log.info("httpplus_app_get2 headers", json.encode(response.headers or {}))
|
||||
body = response.body:query()
|
||||
log.info("httpplus_app_get2 body", body and (body:len()>512 and body:len() or body) or "nil")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- http get下载压缩数据的功能演示
|
||||
local function httpplus_app_get_gzip()
|
||||
local body
|
||||
-- https get请求https://devapi.qweather.com/v7/weather/now?location=101010100&key=0e8c72015e2b4a1dbff1688ad54053de网页内容,超时时间为3秒
|
||||
-- 如果请求成功,请求的数据保存到response.body中
|
||||
local code, response = httpplus.request({url="https://devapi.qweather.com/v7/weather/now?location=101010100&key=0e8c72015e2b4a1dbff1688ad54053de"})
|
||||
log.info("httpplus_app_get_gzip", code==200 and "success" or "error", code)
|
||||
if code==200 then
|
||||
log.info("httpplus_app_get_gzip headers", json.encode(response.headers or {}))
|
||||
body = response.body:query()
|
||||
log.info("httpplus_app_get_gzip body", body and (body:len()>512 and body:len() or body) or "nil")
|
||||
end
|
||||
|
||||
-- 如果请求成功
|
||||
if code == 200 then
|
||||
-- 从body的第11个字节开始解压缩
|
||||
local uncompress_data = miniz.uncompress(body:sub(11,-1), 0)
|
||||
if not uncompress_data then
|
||||
log.error("httpplus_app_get_gzip uncompress error")
|
||||
return
|
||||
end
|
||||
|
||||
local json_data = json.decode(uncompress_data)
|
||||
if not json_data then
|
||||
log.error("httpplus_app_get_gzip json.decode error")
|
||||
return
|
||||
end
|
||||
|
||||
log.info("httpplus_app_get_gzip json_data", json_data)
|
||||
log.info("httpplus_app_get_gzip", "和风天气", json_data.code)
|
||||
if json_data.now then
|
||||
log.info("httpplus_app_get_gzip", "和风天气", "天气", json_data.now.text)
|
||||
log.info("httpplus_app_get_gzip", "和风天气", "温度", json_data.now.temp)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- http post提交表单数据功能演示
|
||||
local function httpplus_app_post_form()
|
||||
-- http post提交表单数据
|
||||
-- http://httpbin.luatos.com/post为回环测试服务器,服务器收到post提交的表单数据后,还会下发同样的表单数据给设备
|
||||
-- 如果请求成功,服务器应答的数据会保存到response.body中
|
||||
local code, response = httpplus.request(
|
||||
{
|
||||
url = "http://httpbin.luatos.com/post",
|
||||
forms = {username="LuatOS", password="123456"}
|
||||
})
|
||||
log.info("httpplus_app_post_form", code==200 and "success" or "error", code)
|
||||
if code==200 then
|
||||
log.info("httpplus_app_post_form headers", json.encode(response.headers or {}))
|
||||
local body = response.body:query()
|
||||
log.info("httpplus_app_post_form body", body and (body:len()>512 and body:len() or body) or "nil")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- http post提交json数据功能演示
|
||||
local function httpplus_app_post_json()
|
||||
local params = {
|
||||
username = "LuatOS",
|
||||
password = "123456"
|
||||
}
|
||||
|
||||
-- http post提交json数据
|
||||
-- http://httpbin.luatos.com/post为回环测试服务器,服务器收到post提交的json数据后,还会下发同样的json数据给设备
|
||||
-- ["Content-Type"] = "application/json" 表示post提交的body数据格式为json格式的数据
|
||||
-- 如果请求成功,服务器应答的数据会保存到response.body中
|
||||
local code, response = httpplus.request(
|
||||
{
|
||||
method = "POST",
|
||||
url = "http://httpbin.luatos.com/post",
|
||||
headers = {["Content-Type"] = "application/json"},
|
||||
body = json.encode(params)
|
||||
})
|
||||
log.info("httpplus_app_post_json", code==200 and "success" or "error", code)
|
||||
if code==200 then
|
||||
log.info("httpplus_app_post_json headers", json.encode(response.headers or {}))
|
||||
local body = response.body:query()
|
||||
log.info("httpplus_app_post_json body", body and (body:len()>512 and body:len() or body) or "nil")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- http post提交纯文本数据功能演示
|
||||
local function httpplus_app_post_text()
|
||||
-- http post提交纯文本数据
|
||||
-- http://httpbin.luatos.com/post为回环测试服务器,服务器收到post提交的纯文本数据后,还会下发同样的纯文本数据给设备
|
||||
-- ["Content-Type"] = "text/plain" 表示post提交的body数据格式为纯文本格式的数据
|
||||
-- 如果请求成功,服务器应答的数据会保存到response.body中
|
||||
local code, response = httpplus.request(
|
||||
{
|
||||
method = "POST",
|
||||
url = "http://httpbin.luatos.com/post",
|
||||
headers = {["Content-Type"] = "text/plain"},
|
||||
body = "This is a raw text message from LuatOS device"
|
||||
})
|
||||
log.info("httpplus_app_post_text", code==200 and "success" or "error", code)
|
||||
if code==200 then
|
||||
log.info("httpplus_app_post_text headers", json.encode(response.headers or {}))
|
||||
local body = response.body:query()
|
||||
log.info("httpplus_app_post_text body", body and (body:len()>512 and body:len() or body) or "nil")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- http post提交xml数据功能演示
|
||||
local function httpplus_app_post_xml()
|
||||
-- [=[ 和 ]=] 之间是一个多行字符串
|
||||
local body = [=[
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<user>
|
||||
<name>LuatOS</name>
|
||||
<password>123456</password>
|
||||
</user>
|
||||
]=]
|
||||
|
||||
-- http post提交xml数据
|
||||
-- http://httpbin.luatos.com/post为回环测试服务器,服务器收到post提交的xml数据后,还会下发同样的xml数据给设备
|
||||
-- ["Content-Type"] = "text/xml" 表示post提交的body数据格式为xml格式的数据
|
||||
-- 如果请求成功,服务器应答的数据会保存到response.body中
|
||||
local code, response = httpplus.request(
|
||||
{
|
||||
method = "POST",
|
||||
url = "http://httpbin.luatos.com/post",
|
||||
headers = {["Content-Type"] = "text/xml"},
|
||||
body = body
|
||||
})
|
||||
log.info("httpplus_app_post_xml", code==200 and "success" or "error", code)
|
||||
if code==200 then
|
||||
log.info("httpplus_app_post_xml headers", json.encode(response.headers or {}))
|
||||
body = response.body:query()
|
||||
log.info("httpplus_app_post_xml body", body and (body:len()>512 and body:len() or body) or "nil")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- http post提交原始二进制数据功能演示
|
||||
local function httpplus_app_post_binary()
|
||||
local body = io.readFile("/luadb/logo.jpg")
|
||||
|
||||
-- http post提交原始二进制数据
|
||||
-- http://uploadtest.luatos.com/api/upload/jpg为jpg图片上传测试服务器
|
||||
-- 此处将logo.jpg的原始二进制数据做为body上传到服务器
|
||||
-- 上传成功后,电脑上浏览器打开https://uploadtest.luatos.com/upload/jpg/,打开对应的测试日期目录,点击具体的测试时间照片,可以查看上传的照片
|
||||
-- ["Content-Type"] = "application/octet-stream" 表示post提交的body数据格式为原始二进制格式的数据
|
||||
-- 如果请求成功,服务器应答的数据会保存到response.body中
|
||||
-- 因为Air32.com平台已经不开放使用了,所以该DEMO仅作上传照片至服务器的演示作用,使用时请将上传URL修改为您自己的服务器地址
|
||||
-- 或者通过excloud扩展库上传到合宙IOT平台uploadtest.luatos.com
|
||||
local code, response = httpplus.request(
|
||||
{
|
||||
method = "POST",
|
||||
url = "http://uploadtest.luatos.com/api/upload/jpg",
|
||||
headers = {["Content-Type"] = "application/octet-stream"},
|
||||
body = body
|
||||
})
|
||||
log.info("httpplus_app_post_binary", code==200 and "success" or "error", code)
|
||||
if code==200 then
|
||||
log.info("httpplus_app_post_binary headers", json.encode(response.headers or {}))
|
||||
body = response.body:query()
|
||||
log.info("httpplus_app_post_binary body", body and (body:len()>512 and body:len() or body) or "nil")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- http post文件上传功能演示
|
||||
local function httpplus_app_post_file()
|
||||
-- hhtplus.request接口支持单文件上传、多文件上传、单文本上传、多文本上传、单/多文本+单/多文件上传
|
||||
-- https://airtest.luatos.com/iot/luat_test_file/add 只支持单文件上传或者单文件+单文本上传
|
||||
-- 要求上传的文件name必须使用"f",上传的文本name必须使用"params"
|
||||
-- 所以此处仅演示了单文件+单文本上传功能,并且"f"和"params"不能改成其他名字,否则会出现上传失败的应答
|
||||
-- 测试接口的响应说明:
|
||||
-- 成功:HTTP 200 OK:{"code":0,"value":"上传成功"};
|
||||
-- 失败:HTTP 状态码非 200 OK 或是 200 OK 但 code 不为 0
|
||||
-- 如何在网页端查看上传的文件:
|
||||
-- 在浏览器中打开https://iot.luatos.com/#/p8000/netlab_file_server,即可查看上传的文件;
|
||||
-- 如果你自己的http服务支持更多类型的文本/文件混合上传,可以打开注释自行验证
|
||||
local code, response = httpplus.request(
|
||||
{
|
||||
url = "https://airtest.luatos.com/iot/luat_test_file/add",
|
||||
files =
|
||||
{
|
||||
["f"] = "/luadb/logo.jpg",
|
||||
-- ["logo1.jpg"] = "/luadb/logo.jpg",
|
||||
},
|
||||
forms =
|
||||
{
|
||||
["params"] = json.encode({
|
||||
username = "LuatOS",
|
||||
password = "123456"
|
||||
}),
|
||||
-- ["username"] = "LuatOS",
|
||||
-- ["password"] = "123456",
|
||||
},
|
||||
})
|
||||
log.info("httpplus_app_post_file", code==200 and "success" or "error", code)
|
||||
if code==200 then
|
||||
log.info("httpplus_app_post_file headers", json.encode(response.headers or {}))
|
||||
local body = response.body:query()
|
||||
log.info("httpplus_app_post_file body", body and (body:len()>512 and body:len() or body) or "nil")
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- http app task 的任务处理函数
|
||||
local function httpplus_app_task_func()
|
||||
while true do
|
||||
-- 如果当前时间点设置的默认网卡还没有连接成功,一直在这里循环等待
|
||||
while not socket.adapter(socket.dft()) do
|
||||
log.warn("httpplus_app_task_func", "wait IP_READY", socket.dft())
|
||||
-- 在此处阻塞等待默认网卡连接成功的消息"IP_READY"
|
||||
-- 或者等待1秒超时退出阻塞等待状态;
|
||||
-- 注意:此处的1000毫秒超时不要修改的更长;
|
||||
-- 因为当使用exnetif.set_priority_order配置多个网卡连接外网的优先级时,会隐式的修改默认使用的网卡
|
||||
-- 当exnetif.set_priority_order的调用时序和此处的socket.adapter(socket.dft())判断时序有可能不匹配
|
||||
-- 此处的1秒,能够保证,即使时序不匹配,也能1秒钟退出阻塞状态,再去判断socket.adapter(socket.dft())
|
||||
sys.waitUntil("IP_READY", 1000)
|
||||
end
|
||||
|
||||
-- 检测到了IP_READY消息
|
||||
log.info("httpplus_app_task_func", "recv IP_READY", socket.dft())
|
||||
|
||||
-- 普通的http get请求功能演示
|
||||
httpplus_app_get()
|
||||
-- http get下载压缩数据的功能演示
|
||||
httpplus_app_get_gzip()
|
||||
-- http post提交表单数据功能演示
|
||||
httpplus_app_post_form()
|
||||
-- -- http post提交json数据功能演示
|
||||
httpplus_app_post_json()
|
||||
-- http post提交纯文本数据功能演示
|
||||
httpplus_app_post_text()
|
||||
-- http post提交xml数据功能演示
|
||||
httpplus_app_post_xml()
|
||||
-- http post提交原始二进制数据功能演示
|
||||
httpplus_app_post_binary()
|
||||
-- http post文件上传功能演示
|
||||
httpplus_app_post_file()
|
||||
|
||||
-- 60秒之后,循环测试
|
||||
sys.wait(60000)
|
||||
end
|
||||
end
|
||||
|
||||
--创建并且启动一个task
|
||||
--运行这个task的处理函数httpplus_app_task_func
|
||||
sys.taskInit(httpplus_app_task_func)
|
||||
Reference in New Issue
Block a user