首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Lua Copas,帮助澄清如何处理多个用户

Lua Copas,帮助澄清如何处理多个用户
EN

Stack Overflow用户
提问于 2011-06-01 04:02:06
回答 2查看 657关注 0票数 1

我有点困惑,认为这将是一个简单的答案,但我的搜索对我没有多大帮助:(我想做一个skt:发送到任何地方。我可以把它作为一个参数发送到OutToUser函数中,但是我会有很多不同的地方,我想在那里这样做,并且感觉会变得太混乱。我试着存储类似于Server.connectionskey = skt的东西,其中key是主机和端口,但是当我需要时,我想不出如何再次获得主机和端口。

有什么好办法吗?

编辑我得到,这是一个范围问题,但没有看到一个好的解决方案,因为我是新手lua。

代码语言:javascript
复制
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()
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-06-01 16:28:37

您可以在处理程序的作用域中定义OutToUser:

代码语言:javascript
复制
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声明的变量),即使它们离开了该作用域--您可以使用它作为替代解决方案,将希望函数在函数外部的作用域中使用的变量括起来:

代码语言:javascript
复制
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, host, 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("*", 49796)
    copas.addserver(server, 
        function(c) return handler(copas.wrap(c), c:getpeername()) end
    )
    copas.loop()
end

请注意这两个示例中使用的local关键字:如果忽略local,名称将完全忽略该范围,并进入/从全球环境进入/来自全球环境(与其他表一样,这只是一个表:当您调用新的Lua状态时,它被放置在全局_G中),这不是您想要的。

将变量保持在局部变量的范围内,而不是使用全局变量是很重要的。例如,这两种功能:

代码语言:javascript
复制
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

因为它们的变量没有被定义为本地变量,所以它们会破坏彼此的数据,将自己的财物放在任何人可以滥用的地方,而且通常表现得就像水滴一样:

代码语言:javascript
复制
--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!
票数 1
EN

Stack Overflow用户

发布于 2011-06-01 07:15:09

我认为您所需要做的就是让OutToUser函数也接受skt参数,并从处理程序内部传递它。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6196122

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档