Lua Copas,帮助阐明如何处理多个用户

问题描述

|| 我有点困惑,认为这将是一个简单的答案,但是我的搜索对我没有太大帮助:(我希望能够在任何地方进行skt:send。我可以将其发送到OutToUser函数中作为参数,但是我将在很多地方都想这样做,感觉会变得太乱了。我尝试将其存储为类似Server.connections [key] = skt的键,其中key是主机和端口,但是在以后需要时无法弄清楚如何再次获得主机和端口。 有什么好的解决方案吗? 编辑我知道这是一个范围问题,但由于我是lua的新手,所以看不到一个好的解决方案。
require \"copas\"
Server = {}
function Server:new()
    local object = {}
    setmetatable(object,{ __index = Server })
    return object
end

function Server:init()
    function handler(skt,host,port)
        while true do
            data = skt:receive()
            if data == \"quit\" then
                -- isn\'t going to work
                OutToUser(data)

                -- this would work fine of course
                -- skt:send(data .. \"\\r\\n\")
            end
        end
    end

    server = socket.bind(\"*\",49796)
    copas.addserver(server,function(c) return handler(copas.wrap(c),c:getpeername()) end
    )
    copas.loop()
end

function OutToUser(data)
    skt:send(data .. \"\\r\\n\")
end

server = Server:new()
server:init()
    

解决方法

        您可以在处理程序的范围内定义OutToUser:
function Server:init()
    local function handler(skt,host,port)

        --make the function local to here
        local function OutToUser(data)
            --references the skt variable in the enclosing scope
            --(the handler function)
            skt:send(data .. \"\\r\\n\")
        end

        while true do
            data = skt:receive()
            if data == \"quit\" then
                OutToUser(data)
            end
        end
    end

    local server = socket.bind(\"*\",49796)
    copas.addserver(server,function(c) return handler(copas.wrap(c),c:getpeername()) end
    )
    copas.loop()
end
函数始终可以在它们的作用域中引用变量(函数参数和用
local
声明的变量),即使它们离开了该作用域-您也可以将其用作替代解决方案,在其中将要使用的函数包含在变量中功能范围外:
local function makeOTU(skt)

    --skt is visible in the scope of the function
    --that gets returned as a result

    return function(data)
        skt:send(data .. \"\\r\\n\")
    end
end

function Server:init()
    local function handler(skt,port)

    --create a function that references skt
    --as part of its closure
    local OutToUser = makeOTU(skt)

        while true do
            data = skt:receive()
            if data == \"quit\" then
                -- OutToUser is still referencing the
                -- skt from the call to makeOTU()
                OutToUser(data)
            end
        end
    end

    local server = socket.bind(\"*\",c:getpeername()) end
    )
    copas.loop()
end
请注意,在这两个示例中都使用了
local
关键字:如果忽略
local
,则名称将完全忽略作用域,并进入/来自全局环境(与其他任何表一样,它是一个表:当您调用new Lua状态,它放在全局
_G
中),这不是您想要的。 将变量保持在局部变量而不是使用全局变量很重要。以以下两个功能为例:
local function yakkity(file,message)

    line = message .. \'\\n\' --without local,--equivalent to _G[\"line\"] = message

    function yak() --without local,--equivalent to _G[\"yak\"] = function()

        file:write(line) --since no local \"line\" is defined above,--equivalent to file:write(_G[\"line\"])
    end
    for i=1,5 do
        yak()
    end
end

local function yakker(file,message)
    line = message .. \'\\n\' --without local,--equivalent to _G[\"line\"] = message

    return function()
        file:write(line) --again,since no local \"line\" is defined above,--equivalent to file:write(_G[\"line\"])
    end
end
由于未将变量定义为局部变量,因此它们会互相破坏数据,将其物品摆放在任何人都可以滥用它们的地方,并且通常表现得像污点一样:
--open handles for two files we want:
local yesfile = io.open (\"yesyes.txt\",\"w\")
local nofile = io.open (\"no.txt\",\"w\")

--get a function to print \"yes!\" - or,rather,--print the value of _G[\"line\"],which we\'ve defined to \"yes!\".
--We\'ll see how long that lasts...
local write_yes = yakker(yesfile,\"yes!\")

--Calling write_yes() now will write \"yes!\" to our file.
write_yes()

--when we call yakkity,though,it redefines the global value of \"line\"
--(_G[\"line\"]) - as well as defining its yak() function globally!
--So,while this function call does its job...
yakkity(nofile,\"oh no!\")

--calling write_yes(),which once again looks up the value of _G[\"line\"],--now does the exact OPPOSITE of what it\'s supposed to-
write_yes() --this writes \"oh no!\" to yesfile!

--additionally,we can still write to the nofile handle we passed to yakkity()
--by calling the globally-defined yak() function!
yak() --this writes a sixth \"oh no!\" to nofile!

--even once we\'re done with the file and close our handle to it...
nofile:close()

--yak() still refers to that handle and will still try to write to it!
yak() --tries to write to the closed file handle and throws an error!
    ,        我想您需要做的就是让
OutToUser
函数也接受skt参数,并从处理程序内部传递它。     

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...