Skip to content

http — HTTP 客户端 ​

网络通信六个库的分工:http / mqtt / tcp / udp / websocketserver / net

模块名:http

发起 HTTP/HTTPS 的 GET/POST 请求,支持同步和异步两种方式。同步请求会阻塞当前 Lua 执行直到收到响应或超时(内部固定 15 秒);异步请求在后台发起,结果通过消息队列回到 Lua 主循环执行回调,不阻塞脚本。

多网卡机型可以在每次请求时指定出口网卡 IP,用来强制走以太网或走 WiFi。

函数总览 ​

库级函数 ​

函数作用
http.creat(string, string, ...)创建 HTTP 客户端对象,可预设 URL 和出口网卡
http.get(string, string, ...)直接传 URL 的同步 GET
http.post(string, string, ...)直接传 URL 的同步 POST

对象方法 ​

方法作用
client:add_head添加或删除请求头
client:get用对象已配置的 URL 和头部做同步 GET
client:post同步 POST
client:get_asy异步 GET,结果走回调
client:post_asy异步 POST,结果走回调

本模块不注册任何常量。


http.creat ​

lua
http.creat([url, ip]) --> client

创建 HTTP 客户端对象。两个参数都可省略。

参数

#参数类型必填默认值说明
1urlstring否—请求地址,可在此预设,也可在 get_asy/post_asy 时再传
2ipstring否—出口网卡的本地 IP,多网卡环境用于指定从哪块网卡发起

返回值

类型说明
userdataHTTP 客户端对象。必须用变量接住,否则可能被 GC 回收

示例

lua
local client = http.creat("http://api.example.com/data")

http.get ​

lua
http.get(url, [ip]) --> string | nil, string

同步 GET,不需要先创建对象。

参数

#参数类型必填默认值说明
1urlstring是—请求地址
2ipstring否—出口网卡 IP

返回值

类型说明
string成功返回响应体;服务端无返回体时是空串 ""
nil, string失败返回 nil 和错误信息 "HTTP GET request failed"

示例

lua
local data, err = http.get("http://api.example.com/data")
if not data then print("请求失败:", err) end

说明

  • 这种简单模式每次调用都临时创建客户端,无法带自定义请求头。需要自定义头部时用 http.creat + client:get。

http.post ​

lua
http.post(url, body, [ip]) --> string | nil, string

同步 POST,不需要先创建对象。

参数

#参数类型必填默认值说明
1urlstring是—请求地址
2bodystring是—请求体,可为二进制
3ipstring否—出口网卡 IP

返回值

类型说明
string成功返回响应体;无返回体时是空串 ""
nil, string失败返回 nil 和 "HTTP POST request failed"

client:add_head ​

lua
client:add_head(name, value)

添加或覆盖一个请求头。

参数

#参数类型必填默认值说明
1namestring是—头部名称
2valuestring是—头部值。传空字符串会删除该头部

返回值

无返回值。

示例

lua
client:add_head("Content-Type", "application/json")
client:add_head("Authorization", "Bearer " .. token)
client:add_head("User-Agent", "")            -- 删除该头部

client:get ​

lua
client:get([ip]) --> string | nil, string

用对象已配置的 URL 和请求头做同步 GET。

参数

#参数类型必填默认值说明
1ipstring否—运行时切换出口网卡 IP

返回值

同 http.get。


client:post ​

lua
client:post(body, [ip]) --> string | nil, string

用对象已配置的 URL 和请求头做同步 POST。

参数

#参数类型必填默认值说明
1bodystring是—请求体
2ipstring否—运行时切换出口网卡 IP

返回值

同 http.post。


client:get_asy ​

lua
client:get_asy(url, callback, [ip])

异步 GET。不阻塞脚本,结果通过回调返回,回调在 Lua 主循环中执行。

参数

#参数类型必填默认值说明
1urlstring是—请求地址(不使用 creat 时预设的 URL)
2callbackfunction是—结果回调,签名见下。类型不是 function 会直接报错
3ipstring否—出口网卡 IP

回调签名

lua
function(errcode, data, datalen)
参数类型说明
errcodeinteger错误码,0 表示成功
datastring响应数据
dataleninteger响应数据长度

返回值

无返回值。

示例

lua
local client = http.creat()
client:get_asy("http://api.example.com/data", function(errcode, data, datalen)
    if errcode == 0 then
        print("收到", datalen, "字节:", data)
    else
        print("请求失败,错误码", errcode)
    end
end)

client:post_asy ​

lua
client:post_asy(url, body, callback, [ip])

异步 POST。

参数

#参数类型必填默认值说明
1urlstring是—请求地址
2bodystring是—请求体
3callbackfunction是—结果回调,签名同 get_asy
4ipstring否—出口网卡 IP

返回值

无返回值。

示例

lua
local client = http.creat()
client:add_head("Content-Type", "application/json")
client:post_asy("http://api.example.com/upload",
    json.encode({ temp = plc.df(100) }),
    function(errcode, data)
        print(errcode == 0 and "上报成功" or "上报失败")
    end)

例程 ​

每个例程都是可直接下载运行的完整脚本:注册完定时器后脚本就结束,固件自动进入消息泵。 API 只用本页已文档化的函数;所有例程遵循统一模板「场景 / 完整代码 / 要点 / 验证方法 / 注意事项」。

例程 1:开机拉一次云端阈值到本地 D 寄存器 ​

适用:LP3201 / LP3202 / LP3203 / LP3222 / LP3232 / LP3288 / 软PLC模拟器 | 依赖模块:http json timer plc | 难度:★☆☆

场景:阈值、量程这类参数写在服务端,设备每次上电拉一次写进 D200 / D201,梯形图照常比大小 —— 参数改一次服务端即可,不用重新下载 Lua。拉失败就保留上次的值,绝不用半截数据覆盖。

完整代码(可直接下载运行):

lua
-- 上电 5 秒后拉一次配置;失败或格式不对都不改写本地 D
local CFG = "http://192.168.1.10:8080/api/config/" .. plc.plc_name()

httpc = http.creat(CFG)                -- 必须长期持有,不要用完即弃的局部对象
httpc:add_head("Accept", "application/json")

timer.start(5000, function()
    local body, err = httpc:get()
    if not body then
        print("拉配置失败:", err, ",保持 D200/D201 原值")
        return
    end

    local ok, cfg = pcall(json.decode, body)
    if not (ok and type(cfg) == "table") then
        print("返回不是 JSON:", body)
        return
    end

    -- 现场约定温度单位 0.1℃,用整数存 D,梯形图里直接 CMP 比较
    if cfg.temp_hi ~= nil then plc.d(200, tonumber(cfg.temp_hi) or plc.d(200)) end
    if cfg.temp_lo ~= nil then plc.d(201, tonumber(cfg.temp_lo) or plc.d(201)) end
    print("配置已生效 hi=", plc.d(200), "lo=", plc.d(201))
end, true)                              -- true = 一次性定时器

要点:

  • httpc:get() 用 creat 时预设的 URL,能带自定义头部;http.get(url) 那种一次性写法不行。
  • 同步接口会阻塞整个事件循环最长 15 秒(网络不好时的内部固定超时),所以只用在上电一次性任务上,周期任务看例程 3。
  • 第三参 true 让定时器只跑一次,跑完自动释放,不用 stop()。
  • json.decode 必须 pcall 包住:服务端返回 HTML 错误页(HTTP 200 但内容不是 JSON)是最常见的坑,pcall 才能稳住。
  • tonumber(cfg.temp_hi) or plc.d(200):字段缺失或类型不对时保持原值,宁可不更新也不要写进 0。

验证方法:

  1. PC 上准备一个返回 {"temp_hi":350,"temp_lo":100} 的接口(改例程里的 IP/端口即可)。
  2. 下载脚本、重启设备,5 秒后日志打印 配置已生效 hi=350 lo=100。
  3. 上位机「在线监视」里看 D200=350、D201=100。
  4. 关掉服务端再重启:日志打印「拉配置失败」,D200 / D201 保持上一次的值不被清空。

注意事项:

  • 服务端返回 HTML 错误页时 body 非 nil(HTTP 200 也照样成功返回),所以要 pcall(json.decode) 后再看字段,不能只看有没有返回值。
  • 同步 get/post 会卡住整个事件循环,把它放进短周期定时器会让其它任务一起卡死。
  • 客户端对象被 GC 回收会导致请求途中失效,例程里用全局变量持有。

其余例程(各自一页) ​

注意事项 ​

  • 同步 get/post 会阻塞整个 Lua 事件循环,网络较慢时定时器和其它回调都会停止推进。在 timer 回调里应统一使用异步接口。
  • 异步回调在主循环里执行,不是独立线程,回调内不要做长阻塞操作。
  • 客户端对象必须用变量长期持有,否则请求返回前对象可能被 GC 回收。
  • 简单模式 http.get(url) 无法携带请求头,需要认证的接口应使用对象模式。

LPPLC 工业物联网云平台 · 软硬件与云平台全栈自研