关于luasocket:Lua套接字异步调用

Lua socket asynchronous calls

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

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


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
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\
\
\
\
"
)
        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 ("\
"
" .. 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-ev做所有的IO多路复用工作。这是一个事件循环的实现,类似于node.js背后的实现。一线程,无种族。


您可能会在luaThread中找到一些启发。其演示之一是异步wget

最近开发的线程库lua-llthreads通过lua-zmq支持ZMQ"充当并发框架的套接字库"