Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Nginx openrestylua脚本只工作一次_Nginx_Lua_Openresty - Fatal编程技术网

Nginx openrestylua脚本只工作一次

Nginx openrestylua脚本只工作一次,nginx,lua,openresty,Nginx,Lua,Openresty,以下代码按预期工作,但只执行一次 require("loadCheckfile") require("checkValPairs") local checklist = loadCheckfile("/home/myname/code/workbench/src/check.lst") local keyList = {} local valList = {} -- Load GET arguments into tables local args = ngx.req.get_uri_a

以下代码按预期工作,但只执行一次

require("loadCheckfile")  
require("checkValPairs")
local checklist = loadCheckfile("/home/myname/code/workbench/src/check.lst")

local keyList = {}
local valList = {}

-- Load GET arguments into tables
local args = ngx.req.get_uri_args()
for key, val in pairs(args) do
    table.insert(keyList, key)
    table.insert(valList, val)
end

-- show values in table (just for testing)
ngx.say(unpack(keyList))
ngx.say(unpack(valList))


local key1

-- search for keywords and look them up in the checklist
for i = 1, table.maxn(keyList) do
    if keyList[i] == "user" then
        key1 = i
        for j = 1, table.maxn(keyList) do
            if keyList[j] == "pass" then
                doesFit = checkValPairs(checklist, keyList[key1], valList[key1], keyList[j], valList[j])
            end
        end
    end
end

-- Show wether the combination fits or not
ngx.say(doesFit)
在第二次运行时,即使是从新的浏览器窗口,我也会遇到以下错误:

*1 lua条目线程中止:运行时错误:/home/myname/code/workbench/src/handler。lua:3:尝试调用全局“loadCheckfile”(一个nil值)

nginx.conf(仅用于开发,不是最终版本):

loadCheckfile.lua:

local function fillChecklistTable(checklist, valueLine) 
    repeat
        firstValLength = string.find(valueLine,"=")
        firstVal = string.sub(valueLine, 1, firstValLength-1)

        valueLine = string.sub(valueLine, firstValLength+1)

        secondValLength = string.find(valueLine, ",")

        if secondValLength ~= nil then
            secondVal = string.sub(valueLine, 1, secondValLength-1)
        else
           secondVal = valueLine
        end

        if checklist[firstVal] == nil then
            checklist[firstVal] = {secondVal}
        else
            table.insert(checklist[firstVal], secondVal)
        end

        if secondValLength ~= nil then
            valueLine = string.sub(valueLine, secondValLength+1)
        else
            valueLine = nil
        end

     until valueLine == nil
end

checklist = {}

function loadCheckfile(checkfile)
    local values = io.open(checkfile)
    local valueLine = values:read()

    while valueLine ~= nil do
        fillChecklistTable(checklist, valueLine)
        valueLine = values:read()
    end
    return checklist
end
有人知道这家伙又做错了什么吗?提前谢谢

更新:

汉德勒·卢阿

checklist = {}

local checkFile = require("loadCheckfile")
local checkPairs = require("checkValPairs")

local checklist = checkFile.loadCheckfile("/home/myname/code/workbench/src/pw_list.txt")

local keyList = {}
local valList = {}

local args = ngx.req.get_uri_args()
for key, val in pairs(args) do
    table.insert(keyList, key)
    table.insert(valList, val)
end


ngx.say(unpack(keyList))
ngx.say(unpack(valList))


local key1

for i = 1, table.maxn(keyList) do
    if keyList[i] == "user" then
        key1 = i
        for j = 1, table.maxn(keyList) do
            if keyList[j] == "pass" then
                doesFit = checkValPairs(checklist, keyList[key1], valList[key1], keyList[j], valList[j])
            end
        end
    end
end

ngx.say(doesFit)
loadCheckfile.lua

module("loadCheckfile", package.seeall)

local function fillChecklistTable(checklist, valueLine) 
    repeat
        firstValLength = string.find(valueLine,"=")
        firstVal = string.sub(valueLine, 1, firstValLength-1)

        valueLine = string.sub(valueLine, firstValLength+1)

        secondValLength = string.find(valueLine, ",")

        if secondValLength ~= nil then
            secondVal = string.sub(valueLine, 1, secondValLength-1)
        else
            secondVal = valueLine
        end

        if checklist[firstVal] == nil then
            checklist[firstVal] = {secondVal}
        else
            table.insert(checklist[firstVal], secondVal)
        end

        if secondValLength ~= nil then
            valueLine = string.sub(valueLine, secondValLength+1)
        else
            valueLine = nil
        end

    until valueLine == nil
end

checklist = {}

function loadCheckfile.loadCheckfile(checkfile)
    local values = io.open(checkfile)
    local valueLine = values:read()

    while valueLine ~= nil do
        fillChecklistTable(checklist, valueLine)
        valueLine = values:read()
    end
    return checklist
end
据我所知,我只将模块放入loadCheckfile.lua和checkValPairs.lua中。但即使把它放进
handler.lua不起作用(只是需要尝试一下)

使用
lua\u code\u cache off
是一个很大的性能问题,因为它将一次又一次地执行代码。试试这个

local checkFile = require("loadCheckfile")  
local checkPairs = require("checkValPairs")
local checklist = checkFile.loadCheckfile("/home/myname/code/workbench/src/check.lst")

让我知道这是否有效,我将添加一个解释

注意

请不要使用此解决方案。虽然它确实有效,但并不好。 我将把它留在这里,以便理解其中一个答案

原始答案:

我的问题的解决方案是通过nginx.conf使模块成为全局的

因此,我在配置中插入了一个
init_by_lua_文件
,调用一个预加载的lua文件,该文件包含了我需要的所有函数,在全局级别上提供了该函数

.conf:

user root;

worker_processes 1;
daemon off;  #used for developing purpose
error_log /dev/stdout warn; #as well for developing

events {
    worker_connections 32;
}


http {
    default_type text/html;
    access_log off;

    lua_package_path '/home/myname/code/workbench/src/?.lua;;'; 

    init_by_lua_file '/home/myname/code/workbench/src/preLoader.lua';

    server {
        listen 80;

        location / {
            content_by_lua_file /home/myname/code/workbench/src/handler.lua;
        }
    }
}
新的preload.lua:

require("loadCheckfile")
require("checkValPairs")
checklist = loadCheckfile("/home/myname/code/workbench/src/check.list")
最后是handler.lua:

local keyList = {}
local valList = {}

-- Load GET arguments into tables
local args = ngx.req.get_uri_args()
for key, val in pairs(args) do
    table.insert(keyList, key)
    table.insert(valList, val)
end

-- show values in table (just for testing)
ngx.say(unpack(keyList))
ngx.say(unpack(valList))


local key1

-- search for keywords and look them up in the checklist
for i = 1, table.maxn(keyList) do
    if keyList[i] == "user" then
        key1 = i
        for j = 1, table.maxn(keyList) do
            if keyList[j] == "pass" then
                 doesFit = checkValPairs(checklist, keyList[key1], valList[key1], keyList[j], valList[j])
            end
        end
    end
end

-- Show wether the combination fits or not
ngx.say(doesFit)

你的解决方案应该是可行的,但是有一些事情需要知道

OpenResty为每个请求创建一个具有全新全局环境的协同程序(Lua绿色线程),但是
require()
只加载一次模块,不再执行其
主块。所以,您在这些模块中设置的所有全局变量仅在第一次请求期间存在。此外,如果您的处理程序进行i/o操作,则会有一个窗口供第二个请求到达并窃取其全局部分,因此不会完成任何请求。准确的解决方案是永远不要在OpenResty中的模块中设置全局变量(在普通Lua中也是如此,因为破坏
\u G
通常是个坏主意),而是遵循标准的模块习惯用法:

-- mymod.lua

local M = { }

local function private() -- for internal use
    ...
end

function M.public() -- to be 'exported'
    ...
end

return M -- this will be returned from require


-- uses_mymod.lua

local mymod = require 'mymod' -- mymod is M from above

mymod.public()
通过这种方式,模块创建一个包含函数的表,而不是将它们设置为全局函数,并将其返回到
require()
require()
将在每次调用时返回它

当您对本地函数的可见性规则感到厌倦时,请引入另一个
localm={}
或任何您想命名的名称,并将所有私有项存储在那里。在这变得难看之后,请选择高级主题,如Lua环境(
setfenv()
setmetatable()
)。如果您不想了解详细信息,请在每个模块的
localm={}
前面加上这一行:

setfenv(1, setmetatable({ }, { __index = getfenv(0) }))

您的所有全局文件都是该模块的本地文件,因此您可以避免
m
(但不是
m
,仍然是“导出”所必需的)。

同时发布nginx配置并加载检查文件,以及将lua\u code\u缓存添加到nginx.conf中解决了问题。然而,我非常怀疑这是否适合工作环境。我得到一个错误,行
localchecklist=checkFile.loadCheckfile(“/home/myname/code/workbench/src/check.lst”)
表示试图索引本地“checkFile”(布尔值)将其添加到文件
模块(“loadCheckfile”,package.seeall)的顶部,更改另一个文件的名称,并查看它是否工作。它仍在尝试索引本地“checkFile”(布尔值)。在问题中发布更新的代码以及错误详细信息。谢谢你的努力,我真的觉得我在这件事上抓住了那个笨蛋-谢谢。你的回答帮助我理解了我原来问题中的错误。我从未在模块末尾返回函数,只是返回函数本身中的表。
setfenv(1, setmetatable({ }, { __index = getfenv(0) }))