Вопрос по асинхронным запросам

Tokynogiht

Новичок
Автор темы
23
0
Версия MoonLoader
.027.0-preview
Ознакомился с этим гайдом, на его основе получился следующий скрипт:
Код:
copas = require('copas')
http = require('copas.http')


function main()

    if not isSampfuncsLoaded() or not isSampLoaded() then
        return
    end
    while not isSampAvailable() do
        wait(0)
    end

    sampRegisterChatCommand("auth", rauthCallBack)
    wait(-1)
end

function rauthCallBack(params)
    lua_thread.create(function()
        local list = {
            "http://www.google.com",
            "http://www.microsoft.com",
            "http://www.apple.com",
            "https://www.facebook.com",
            "https://www.yahoo.com",
        }
       
        -- параллельные запросы, обработаются одновременно
        print('parallel')
        for i, url in ipairs(list) do
            print('request', url)
            httpRequest(url, nil, function(response, code, headers, status)
                if response then
                    print(url, 'OK', status)
                else
                    print(url, 'Error', code)
                end
            end)
        end
    end)
end

function httpRequest(request, body, handler) -- copas.http
    -- start polling task
    if not copas.running then
        copas.running = true
        lua_thread.create(function()
            wait(0)
            while not copas.finished() do
                local ok, err = copas.step(0)
                if ok == nil then error(err) end
                wait(0)
            end
            copas.running = false
        end)
    end
    -- do request
    if handler then
        return copas.addthread(function(r, b, h)
            copas.setErrorHandler(function(err) h(nil, err) end)
            h(http.request(r, b))
        end, request, body, handler)
    else
        local results
        local thread = copas.addthread(function(r, b)
            copas.setErrorHandler(function(err) results = {nil, err} end)
            results = table.pack(http.request(r, b))
        end, request, body)
        while coroutine.status(thread) ~= 'dead' do wait(0) end
        return table.unpack(results)
    end
end

Однако, возникла следующая проблема - при первом выполнении команды /auth игру фризист, а при последующих нет. Запросы при этом выполняются асинхронно, как и ожидалось. Что не так и как это можно исправить? В примере для каллбека команды auth создается отдельный поток, но даже с ним все равно проявляется этот единичный фриз.

MoonLoader v.027.0-preview3
 

Kolbasa241

Известный
213
57
Так у тебя стоит щас не асинхронный запрос LOL
1597165415881.png
 

Tokynogiht

Новичок
Автор темы
23
0
Так у тебя стоит щас не асинхронный запрос LOL
Посмотреть вложение 65161
Здравствуйте, комментарий указан верно, автор гайда имел ввиду, что http запросы выполняются одновременно, (все сразу). А асинхронность запросам предоставляет copas, благодаря которому основной поток скрипта lua не блокируется.

Код работает правильно и запросы создаются асинхронного и выполняются параллельно, каждый в своем потоке. Единственное не ясно, почему при ПЕРВОМ http запросе происходит микрофриз, а при всех последующих нет.
 

Rei

Известный
Друг
1,589
1,617
тоже фризит первый раз, только у меня обычный рендер текста, для этого в майн поместил рендер точки на 1 кадр и скрипт проперживается на старте игры

хотя вот у других скриптов с рендером я такого не замечал, может дело в подключении библиотек?
 
  • Нравится
Реакции: Tokynogiht

Kolbasa241

Известный
213
57
Lua:
effil = require"effil"

function asyncHttpRequest(method, url, args, resolve, reject)
    local request_thread = effil.thread(function(method, url, args)
        local requests = require"requests"
        local result, response = pcall(requests.request, method, url, args)
        if result then
            response.json, response.xml = nil, nil
            return true, response
        else
            return false, response
        end
    end)(method, url, args)

    if not resolve then
        resolve = function() end
    end
    if not reject then
        reject = function() end
    end
    lua_thread.create(function()
        local runner = request_thread
        while true do
            local status, err = runner:status()
            if not err then
                if status == "completed" then
                    local result, response = runner:get()
                    if result then
                        resolve(response)
                    else
                        reject(response)
                    end
                    return
                elseif status == "canceled" then
                    return reject(status)
                end
            else
                return reject(err)
            end
            wait(0)
        end
    end)
end


function main()

    if not isSampfuncsLoaded() or not isSampLoaded() then
        return
    end
    while not isSampAvailable() do
        wait(0)
    end

    sampRegisterChatCommand("auth", rauthCallBack)
    wait(-1)
end

function rauthCallBack(params)
    lua_thread.create(function()
        local list = {
            "http://www.google.com",
            "http://www.microsoft.com",
            "http://www.apple.com",
            "https://www.facebook.com",
            "https://www.yahoo.com",
        }
     
        -- асинхронные запросики
        print('Async')
        for i, url in ipairs(list) do
            print("Trying to get a response from "..url)
            asyncHttpRequest("POST", url, nil,
                function(response)
                    print("Answer received from "..url.." | code -"..response.status_code )
                end,
                function(err)
                    print("[Error] Failed to get response from "..url.." | "..err)
                end)
        end
    end)
end

Я этим пользуюсь.
библиотеки - effil и requests
 

Tokynogiht

Новичок
Автор темы
23
0
тоже фризит первый раз, только у меня обычный рендер текста, для этого в майн поместил рендер точки на 1 кадр и скрипт проперживается на старте игры

хотя вот у других скриптов с рендером я такого не замечал, может дело в подключении библиотек?
Рад, что я не одинок в этой проблеме) Жаль, что пока единственное решение это дать профризится при запуске или переходить на другую библиотеку. Может местные асинхроннщики смогут внести ясность.
 

Kolbasa241

Известный
213
57
Рад, что я не одинок в этой проблеме) Жаль, что пока единственное решение это дать профризится при запуске или переходить на другую библиотеку. Может местные асинхроннщики смогут внести ясность.
я же скинул выше метод...
в чём проблема? это асинх запрос ес чо
 

Tokynogiht

Новичок
Автор темы
23
0
Lua:
effil = require"effil"

function asyncHttpRequest(method, url, args, resolve, reject)
    local request_thread = effil.thread(function(method, url, args)
        local requests = require"requests"
        local result, response = pcall(requests.request, method, url, args)
        if result then
            response.json, response.xml = nil, nil
            return true, response
        else
            return false, response
        end
    end)(method, url, args)

    if not resolve then
        resolve = function() end
    end
    if not reject then
        reject = function() end
    end
    lua_thread.create(function()
        local runner = request_thread
        while true do
            local status, err = runner:status()
            if not err then
                if status == "completed" then
                    local result, response = runner:get()
                    if result then
                        resolve(response)
                    else
                        reject(response)
                    end
                    return
                elseif status == "canceled" then
                    return reject(status)
                end
            else
                return reject(err)
            end
            wait(0)
        end
    end)
end


function main()

    if not isSampfuncsLoaded() or not isSampLoaded() then
        return
    end
    while not isSampAvailable() do
        wait(0)
    end

    sampRegisterChatCommand("auth", rauthCallBack)
    wait(-1)
end

function rauthCallBack(params)
    lua_thread.create(function()
        local list = {
            "http://www.google.com",
            "http://www.microsoft.com",
            "http://www.apple.com",
            "https://www.facebook.com",
            "https://www.yahoo.com",
        }
    
        -- асинхронные запросики
        print('Async')
        for i, url in ipairs(list) do
            print("Trying to get a response from "..url)
            asyncHttpRequest("POST", url, nil,
                function(response)
                    print("Answer received from "..url.." | code -"..response.status_code )
                end,
                function(err)
                    print("[Error] Failed to get response from "..url.." | "..err)
                end)
        end
    end)
end

Я этим пользуюсь.
библиотеки - effil и requests

К сожалению крашит без каких-либо ошибок. Вы проверяли эту функцию на работоспособность? Можете сбросить свою папку lib? Возможно у меня не та версия effil
 

Tokynogiht

Новичок
Автор темы
23
0
Lua Requests и EFFIL
Я заходил в самп и тестил там всё, всё работает у меня без каких-либо крашей и ошибок
А как передать какие-то данные в запросы? Пробовал так:
Код:
    asyncHttpRequest("POST", url, {test="test"},
                function(response)
                    print("Answer received from "..url.." | code -"..response.status_code )
                end,
                function(err)
                    print("[Error] Failed to get response from "..url.." | "..err)
    end)
и так
Код:
    asyncHttpRequest("POST", url, '{"test": 100}',
                function(response)
                    print("Answer received from "..url.." | code -"..response.status_code )
                end,
                function(err)
                    print("[Error] Failed to get response from "..url.." | "..err)
    end)

Но на сервер приходит только запрос, без данных