Lua сокет асинхронных вызовов
Я пишу программу, которая использует Lua-сокет для связи с http-сервером. Я использую API-интерфейс "socket.http.request", и я обнаружил, что он является синхронным. Насколько я понимаю, он ждет, пока не получит ответ или не истечет время ожидания. Правильно ли мое понимание? Если это так, я бы предпочел использовать асинхронный API.
Я также нашел другой API "socket.http.request_cb", который вызывает функцию обратного вызова при обработке запроса. Тем не менее, это не похоже на работу здесь. (Этот API недоступен в используемой версии.) Здесь я использую Lua 5.1 и Lua socket 2.0.2. Может кто-нибудь сообщить мне, какая версия Lua или Lua socket имеет этот API?
3 ответа
При подключении: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()
Я делаю все операции мультиплексирования ввода-вывода с lua-ev. Это реализация цикла событий, похожая на ту, что стоит за node.js. Одна нить, никаких гонок.
Вы можете найти вдохновение в luaThread. Одна из его демонстраций - асинхронная wget
,
Недавно разработанная библиотека потоков lua-llthreads поддерживает ZMQ "библиотеку сокетов, которая действует как среда параллелизма" с lua-zmq