Таймауты WinHttpRequest

Я использую скрипт AHK для отправки некоторых запросов POST. Я пытаюсь получить ответ тайм-аут, чтобы я мог выскакивать какое-то сообщение пользователю. Я не могу понять, как использовать метод "SetTimeouts" и "WaitForResponse" См. Код ниже

WebRequest := ComObjCreate("WinHttp.WinHttpRequest.5.1")
WebRequest.SetTimeouts(3000,3000,3000,3000)

openConnection(WebRequest,ip){
   WebRequest.Open("POST", "http://" ip "/cgi/drsLogin",true)
   WebRequest.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded")
   WebRequest.Send("action=login&username=admin&password=admin")
   time := WebRequest.WaitForResponse(2)

   if (time = -1) {
    addTextToGui("Connection Timeout")
   }
   else{
     return
   }
 return
}

2 ответа

Решение

AutoHotkey нравится значения в функциях, которые будут заключены в кавычки.

Попробуйте изменить:

WebRequest.SetTimeouts(3000,3000,3000,3000)

в

WinHttpReq.SetTimeouts("30000", "30000", "30000", "30000")

Изменить: Хорошо, кажется, я был неправ, и оба метода работают.

Я проверил вышеупомянутое, используя этот сайт: http://tmplinshi.sinaapp.com/test/timeout-test-20s.php

В коде ниже SetTimouts Наш тест настроен на ответ в течение 20 секунд, поэтому это гарантирует тайм-аут.

WinHttpReq := ComObjCreate("WinHttp.WinHttpRequest.5.1")
WinHttpReq.SetTimeouts("10000", "10000", "10000", "10000")
WinHttpReq.Open("GET", "http://tmplinshi.sinaapp.com/test/timeout-test-20s.php", false)
WinHttpReq.Send()
WinHttpReq.WaitForResponse()
webpage := WinHttpReq.ResponseText
MsgBox % webpage

Я получаю сообщение об ошибке тайм-аута, но это нарушает работу скрипта и все еще не отвечает, как получить сообщение о тайм-ауте?

Ну, так как мы получаем ошибку тайм-аута, это означает, что нам нужно добавить обработку ошибок в наш код. Мы сделаем это с помощью Try / Catch.

WinHttpReq := ComObjCreate("WinHttp.WinHttpRequest.5.1")
WinHttpReq.SetTimeouts("10000", "10000", "10000", "10000")

Try { 
WinHttpReq.Open("GET", "http://tmplinshi.sinaapp.com/test/timeout-test-20s.php", false)
WinHttpReq.Send()
WinHttpReq.WaitForResponse()
webpage := WinHttpReq.ResponseText
}
Catch e{
    MsgBox % e
    ExitApp
}

MsgBox % webpage

Хорошо, скрипт больше не ломается, но MsgBox пуст? Это не работает!

Ну, это пустое, потому что наше сообщение об ошибке возвращается из объекта в виде объекта! Изучение e Объект, который я обнаружил, содержит несколько ключей, хранящих данные в виде строк и даже целочисленное значение. Клавиши помечены так: "Дополнительно", "Файл", "Строка", "Сообщение" и "Что...". Итак, давайте посмотрим на сообщение!

WinHttpReq := ComObjCreate("WinHttp.WinHttpRequest.5.1")
WinHttpReq.SetTimeouts("10000", "10000", "10000", "10000")

Try { 
WinHttpReq.Open("GET", "http://tmplinshi.sinaapp.com/test/timeout-test-20s.php", false)
WinHttpReq.Send()
WinHttpReq.WaitForResponse()
webpage := WinHttpReq.ResponseText
}
Catch e{
    MsgBox % e.Message
    ExitApp
}

MsgBox % webpage

Хорошо, теперь я вижу:

0x80072EE2 -
Источник: WinHttp.WinHttpRequest

Описание: Тайм-аут операции

HelpFile: (ноль)

HelpContext: 0

Да, похоже, мы получили наше сообщение об истечении срока действия и кучу другой информации, которую мы, вероятно, не хотим. Итак, что мы можем сделать сейчас - это проанализировать данные, которые мы хотим получить из сообщения! Вот так:

WinHttpReq := ComObjCreate("WinHttp.WinHttpRequest.5.1")
WinHttpReq.SetTimeouts("10000", "10000", "10000", "10000")

Try { 
WinHttpReq.Open("GET", "http://tmplinshi.sinaapp.com/test/timeout-test-20s.php", false)
WinHttpReq.Send()
WinHttpReq.WaitForResponse()
webpage := WinHttpReq.ResponseText
}
Catch e{
    For Each, Line in StrSplit(e.Message, "`n", "`r") {
        Results := InStr(Line, "Description:") 
            ? StrReplace(Line, "Description:")
            : ""
        If (Results <> "")
            Break
    }
    MsgBox % Trim(Results)
    ExitApp
}

MsgBox % webpage

Редактировать:

Забыл упомянуть, что этот метод будет не только перехватывать тайм-ауты, но и различные другие ошибки, такие как недостижимый адрес или недействительный URL, и будет правильно отображать эти ошибки.

Вы можете сами проверить их, зайдя на сайт http://www.isitdownrightnow.com/ и попытавшись использовать приведенный выше код на неработающем сайте. Вы увидите, что это возвращает:

Имя сервера или адрес не могут быть разрешены

Также добавляем символы, которые не принадлежат, или пробелы в URL, который генерирует код:

URL недействителен

Вот еще один способ сделать это. Он немного более читабелен и позволяет вам установить общее время ожидания, а не другое время ожидания более низкого уровня, о котором вы обычно не заботитесь.

WinHttpReq := ComObjCreate("WinHttp.WinHttpRequest.5.1")

timedOut := False
WinHttpReq.Open("GET", "http://google.com", True)
WinHttpReq.Send()
Sleep, 1     ;timeout: 1 millisecond (will time out)
;Sleep, 4000 ;timeout: 4 seconds (should not time out)

ComObjError(False)
WinHttpReq.Status
If (A_LastError) ;if WinHttpReq.Status was not set (no response received yet)
    timedOut := True
ComObjError(True)

If (timedOut)
    MsgBox, timed out
Else
    MsgBox, didn't time out
Другие вопросы по тегам