Lua套接字异步调用 [英] Lua socket asynchronous calls

查看:94
本文介绍了Lua套接字异步调用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个使用Lua套接字与http服务器通信的程序. 我正在使用的API是"socket.http.request",并且我发现它是同步的.我的理解是,它一直等到得到一些响应或超时. 我的理解正确吗?如果是这样,我宁愿使用异步API.

I am writing a program that uses Lua socket to communicate with a http server. The API that I am using is "socket.http.request", and I have found that it is synchronous. My understanding is that it waits until it gets some response or time outs. Is my understanding correct? If so, I'd prefer to use an asynchronous API.

我还找到了另一个API"socket.http.request_cb",该API在处理请求时会调用回调函数.但是,它似乎在这里不起作用. (此API在我使用的版本上不可用.)我在这里使用Lua 5.1和Lua socket 2.0.2.谁能让我知道该API的哪个版本的Lua或Lua套接字?

I also found another API "socket.http.request_cb", which calls a call back function when the request is processed. However, it doesn't seem to work here. (This API is not available on the version that I'm using.) I'm using Lua 5.1 and Lua socket 2.0.2 here. Could anyone let me know which version of Lua or Lua socket has this API?

推荐答案

使用connection:settimeout()可以设置连接超时.在用于Lua Socket的并行下载器的示例中使用了此示例:

With connection:settimeout() you can set a time out for a connection. This is used in this example of a parallel downloader for Lua Socket:

function download (host, file, port)
    port = port or 80
    print (host, file, port)    
    local connectStatus, myConnection = pcall (socket.connect,host,port)
    if (connectStatus) then
        myConnection:settimeout(0.01) -- do not block you can play with this value
        local count = 0 -- counts number of bytes read
        -- May be easier to do this LuaSocket's HTTP functions
        myConnection:send("GET " .. file .. " HTTP/1.0\r\n\r\n")
        local lastStatus = nil
        while true do
            local buffer, status, overflow = receive(myConnection, lastStatus)
            -- If buffer is not null the call was a success (changed in LuaSocket 2.0)
            if (buffer ~= nil) then
                 io.write("+")
                 io.flush()
                 count = count + string.len(buffer)
            else
                print ("\n\"" .. status .. "\" with " .. string.len(overflow) .. " bytes of " .. file)
                io.flush()
                count = count + string.len(overflow)
            end
            if status == "closed" then break end
                lastStatus=status
            end
        myConnection:close()
        print(file, count)
    else
        print("Connection failed with error : " .. myConnection)
        io.flush()
    end
end

threads = {} -- list of all live threads

function get (host, file, port)
    -- create coroutine
    local co = coroutine.create(
        function ()
            download(host, file, port)
        end)
    -- insert it in the 
    table.insert(threads, co)
end

function receive (myConnection, status)
    if status == "timeout" then
        print (myConnection, "Yielding to dispatcher")
        io.flush()
        coroutine.yield(myConnection)
    end
    return myConnection:receive(1024)
end

function dispatcher ()
    while true do
        local n = table.getn(threads)
        if n == 0 then break end -- no more threads to run
        local connections = {}
        for i=1,n do
            print (threads[i], "Resuming")
            io.flush()
            local status, res = coroutine.resume(threads[i])
            if not res then -- thread finished its task?
                table.remove(threads, i)
                break
            else -- timeout
                table.insert(connections, res)
            end
        end
        if table.getn(connections) == n then
            socket.select(connections)
        end
    end
end

host = "www.w3.org"
get(host, "/TR/html401/html40.txt")
get(host,"/TR/2002/REC-xhtml1-20020801/xhtml1.pdf")
get(host,"/TR/REC-html32.html")
get(host,"/TR/2000/REC-DOM-Level-2-Core-20001113/DOM2-Core.txt")
dispatcher()

这篇关于Lua套接字异步调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆