12

Lua ソケットを使用して http サーバーと通信するプログラムを作成しています。私が使用している API は「socket.http.request」であり、同期的であることがわかりました。私の理解では、応答またはタイムアウトが発生するまで待機します。私の理解は正しいですか?もしそうなら、私は非同期 API を使用したいと思います。

また、リクエストが処理されたときにコールバック関数を呼び出す別の API「socket.http.request_cb」も見つけました。ただし、ここでは機能しないようです。(この API は、私が使用しているバージョンでは使用できません。) ここでは Lua 5.1 と Lua ソケット 2.0.2 を使用しています。Lua または Lua ソケットのどのバージョンがこの API を持っているか教えてもらえますか?

4

3 に答える 3

12

connection:settimeout() を使用すると、接続のタイムアウトを設定できます。これは、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()
于 2011-04-27T19:38:52.863 に答える
1

lua-evを使用してすべての IO 多重化を行っています。これは、node.js の背後にあるものと同様のイベント ループの実装です。1 つのスレッド、レースはありません。

于 2013-11-05T22:42:55.397 に答える
0

luaThreadでインスピレーションが得られるかもしれません。そのデモの 1 つは非同期wgetです。

最近開発されたスレッド ライブラリlu​​a-llthreads は、 lua-zmqZMQの「同時実行フレームワークとして機能するソケット ライブラリ」をサポートします。

于 2011-04-28T15:00:43.817 に答える