net
HTTP + WebSocket。全异步 —— 回调在菜单线程派发,Lua 安全,可直接 gui.set / notify.*。同步 API(get_sync 之类)不提供,会阻塞菜单线程。
生命周期
| 资源 | 卸载行为 |
|---|---|
HTTP 待回调(net.http:*) | 排队中的 response 静默丢弃,不调你的回调 |
WebSocket 客户端(net.ws:connect) | 该脚本打开的连接全部关闭 |
WebSocket server(net.ws_server:listen) | 该脚本打开的 server 全部关闭,所有 client 强制断开 |
WS 客户端连不上 server 时(端口关、超时、URL 错)后台资源自动清理,反复重连不会泄漏内存或线程。net.ws:connect 是即发即忘风格 —— 不需要每次失败手动 :close,可以放心放循环里 retry。
net.http
resp 回调参数字段:status : int, body : string, error : string, ok : bool
net.http:get(url, callback, timeout?)
参数:url : string, callback : function(resp), timeout? : int = 10(秒)
net.http:get(url, options, callback) — 带 headers / 文件下载
参数:url : string, options : table, callback : function(resp)
net.http:post(url, body, content_type, callback, timeout?)
参数:url : string, body : string, content_type : string, callback : function(resp), timeout? : int = 10
net.http:post(url, options, callback) — 带 headers / 自定义 body
参数:url : string, options : table, callback : function(resp)
net.http:request(url, method, options, callback) — 任意 method
参数:url : string, method : string(GET / POST / PUT / DELETE / PATCH 等), options : table, callback : function(resp)
options 表可选字段:
| 字段 | 类型 | 说明 |
|---|---|---|
headers | table<string,string> | 自定义请求头 |
body | string | 请求体(GET 可空) |
content_type | string | 自动合成 Content-Type 头 |
save_to_file | string | 非空时流式写文件而非 resp.body(大文件下载用,沙盒外路径) |
timeout | int | 秒,默认 10 |
net.ws
net.ws:connect(url, callbacks) → ws_id : int
参数:url : string, callbacks : table
callbacks 表中可选字段(每个都是 function):
| 字段 | 签名 |
|---|---|
on_open | function(id : int) |
on_message | function(id : int, msg : string) |
on_error | function(id : int, err : string) |
on_close | function(id : int, code : int, reason : string) |
net.ws:send(id, msg) → bool
net.ws:close(id)
net.ws:is_open(id) → bool
net.ws_server
WebSocket 服务端。仅监听 127.0.0.1(本机 web dashboard / IPC,不开外网)。 脚本卸载时该脚本创建的全部 server 自动关闭,所有 client 强制断开。
net.ws_server:listen(port, callbacks) → WsServer | nil
参数:
port : int— 本机端口(被占用返 nil)callbacks : table— 回调表
| 字段 | 签名 | 说明 |
|---|---|---|
on_open | fn(client : int) | 新 client 完成 handshake |
on_message | fn(client : int, msg : string) | 收到文本 / 二进制消息 |
on_error | fn(client : int, err : string) | 异常 |
on_close | fn(client : int, code : int, reason : string) | client 断开(含远端主动关或本端断) |
返回 WsServer userdata(失败 nil)。
WsServer 方法
| 方法 | 说明 |
|---|---|
srv:send(client, msg) → bool | 给指定 client 发文本消息 |
srv:broadcast(msg) | 给该 server 所有 client 广播 |
srv:disconnect(client, code?, reason?) | 主动断指定 client;code 默认 1000,reason 默认空 |
srv:close() | 关 server + 全部 client + join 内部线程 |
srv:is_open() → bool | server 是否仍在运行 |
srv:client_count() → int | 当前已连接 client 数 |
srv.id | server 数字 id(read-only) |
约束
- 64MB 单消息上限(防恶意大 payload)
- 仅
text(opcode 0x1) 发出方向;text/binary都能接收 - 不支持
wss://(TLS) —— 本机用例不需要 - 不支持 fragmented frame 跨 opcode 的 subprotocol
- 自动响应
ping → pong,不触发用户回调
-- 本机 dashboard:8080 端口,浏览器接 ws://127.0.0.1:8080/
local srv = net.ws_server:listen(8080, {
on_open = function(c) print("client", c, "joined") end,
on_message = function(c, msg) print("got from", c, ":", msg) end,
on_close = function(c, code, reason) print("client", c, "left", code) end,
})
if not srv then return end
-- 每帧广播游戏状态
event.on("frame_update", function(e)
local lp = game.localplayer
if lp then
srv:broadcast(json.encode({hp=lp.health, sh=lp.shield, vel=lp.abs_velocity}))
end
end)
-- 收命令对应处理
event.on("script_unloaded", function(ue)
if ue.script_path == _SCRIPT_PATH then srv:close() end
end)示例
-- HTTP GET(异步)
net.http:get("https://example.com", function(resp)
if resp.ok then
log.info("OK " .. resp.status .. ", body len=" .. #resp.body)
else
log.warn("HTTP fail: " .. (resp.error or ""))
end
end, 3)
-- HTTP POST JSON(旧签名)
net.http:post("https://api.example.com/log",
[[{"event":"hello"}]], "application/json",
function(resp) print(resp.status, resp.ok) end, 5)
-- 带 Authorization 的 GET(options 风格)
net.http:get("https://api.example.com/me", {
headers = { ["Authorization"] = "Bearer " .. token, ["X-Trace-Id"] = "abc" },
timeout = 5,
}, function(resp) log.info(resp.body) end)
-- POST JSON 带自定义 header
net.http:post("https://api.example.com/log", {
headers = { ["Authorization"] = "Bearer " .. token },
body = json.encode({ event = "hello" }),
content_type = "application/json",
}, function(resp) print(resp.status) end)
-- 大文件下载到本地(不占内存)
net.http:get("https://example.com/big.zip", {
save_to_file = "downloads/big.zip",
timeout = 60,
}, function(resp) log.info("downloaded, status=" .. resp.status) end)
-- PUT / DELETE
net.http:request("https://api.example.com/item/42", "DELETE", {
headers = { ["Authorization"] = "Bearer " .. token },
}, function(resp) print(resp.ok) end)
-- WebSocket 4 回调
local ws_id = net.ws:connect("wss://echo.example.com", {
on_open = function(id) net.ws:send(id, "hi") end,
on_message = function(id, msg) log.info("recv " .. msg) end,
on_error = function(id, err) log.warn("err " .. err) end,
on_close = function(id, code, reason) log.info("close " .. code) end,
})