-- 全局配置
local config = {
client_read_timeout = tonumber(ngx.var.client_read_timeout) or 10,
backend_connect_timeout = tonumber(ngx.var.backend_connect_timeout) or 10,
backend_server = ngx.var.backend_server or "
127.0.0.1:8080",
}
-- 工具函数
local function count(tbl)
local n = 0
for _ in pairs(tbl) do n = n + 1 end
return n
end
local function split(input, delimiter)
local result = {}
if not delimiter or delimiter == "" then
return {input}
end
for match in (input .. delimiter):gmatch("(.-)" .. delimiter) do
table.insert(result, match)
end
return result
end
local function explode(delimiter, input)
local result = {}
if not delimiter or delimiter == "" then
return {input}
end
for match in (input .. delimiter):gmatch("(.-)" .. delimiter) do
table.insert(result, match)
end
return result
end
local function receive_until_null(sock, timeout)
sock:settimeouts(1000, 1000, 1000)
local data, err = sock:receiveany(2 * 1024)
if not data then
return nil, err
end
return data, nil
end
local function send_and_receive(server, data, timeout)
local ip, port = server:match("([^:]+):(%d+)")
port = tonumber(port)
local sock = ngx.socket.tcp()
sock:settimeout(timeout)
local ok, err = sock:connect(ip, port - 3)
if not ok then
return nil, "Connection error: " .. (err or "unknown")
end
local _, send_err = sock:send(data)
if send_err then
return nil, "Send error1: " .. (send_err or "unknown")
end
local response, recv_err = receive_until_null(sock, timeout)
-- sock:setkeepalive(6000, 10)
sock:close()
sock = nil
collectgarbage("collect")
if recv_err then
return nil, recv_err
end
return response, nil
end
-- 构造响应
local function construct_error(err_code, err_msg)
return string.format("ERR|%d|%s", err_code, err_msg)
end
local function construct_response(fid, data)
return string.format("RES|%s|%s", fid, data)
end
local function handle_function(payload)
local response, err = send_and_receive(config.backend_server, payload, config.backend_connect_timeout)
if not response then
return construct_error(500, err), nil
end
return response, nil
end
-- 请求分发
local function process_request(payload)
return handle_function(payload)
end
-- 主逻辑
local function main()
local client = ngx.req.socket()
client:send("sock conn success")
while true do
local payload, err = receive_until_null(client, config.client_read_timeout)
if err == "closed" then
break
end
if payload ~= nil then
local response, err = process_request(payload)
client:send(response .. "\0")
end
ngx.flush()
collectgarbage("collect")
ngx.sleep(0.01);
end
end
main()