Lua socket asynchronous calls

前端 未结 3 723
走了就别回头了
走了就别回头了 2020-12-08 17:51

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. M

相关标签:
3条回答
  • 2020-12-08 18:09

    I am doing all IO multiplexing stuff with lua-ev. It an event loop implementation similar to the one behind node.js. One thread, no races.

    0 讨论(0)
  • 2020-12-08 18:10

    You may find some inspiration in luaThread. One of its demos is an asynchronous wget.

    A recently developed threading library lua-llthreads supports the ZMQ "socket library that acts as a concurrency framework" with lua-zmq

    0 讨论(0)
  • 2020-12-08 18:27

    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()
    
    0 讨论(0)
提交回复
热议问题