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中找到一些启发。其演示之一是异步
最近开发的线程库lua-llthreads通过lua-zmq支持ZMQ"充当并发框架的套接字库"