Подскажите как реализовать асинхронный режим работы WinHTTP. Например есть такой код (Proxy Checker):
Но он работает ужасно медленно, кроме того GUI перестаёт перерисовываться и реагировать на события если вызвать эту функцию. А всё из-за того что скрипт ждёт ответа в winHTTP , который будет в случае отсутствия прокси только спустя десятки секунд. Прочитал что winHTTP может посылать следующий запрос не дожидаясь ответа на предыдущий, но как это реализовать незнаю.
Используемые файлы:
WinHTTP.au3
WinHTTPConstants.au3
proxy.txt
Код:
#cs ----------------------------------------------------------------------------
AutoIt Version: 3.3.2.0
Author: Luke
Script Function: test proxy
Template AutoIt script.
#ce ----------------------------------------------------------------------------
#include <Inet.au3>
#include "WinHTTP.au3"
HotKeySet("^{F9}", "Terminate") ;Назначение горячей клавиши. При нажатии ctrl+F9 скрипт закончит свою работу
Dim $MyPublicIP = _GetIP(), $Stop = 0
Dim $sFileProxy = @ScriptDir & "\proxy.txt"
Dim $sFileGoodProxy = @ScriptDir & "\GoodProxy.txt"
ButtonStartClick()
Func ButtonStartClick()
; инициируем WinHTTP;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$hOpen = _WinHttpOpen("testUtility")
If @error Then
MsgBox(48, "Error", "Error initializing the usage of WinHTTP functions.")
Return SetError(1)
EndIf
_WinHttpSetTimeouts($hOpen, 0, 20000, 10000, 10000)
_WinHttpSetOption($hOpen, $WINHTTP_OPTION_DISABLE_FEATURE, $WINHTTP_DISABLE_COOKIES)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$hFileProxy = FileOpen($sFileProxy, 0)
If $hFileProxy = -1 Then
MsgBox(0, "Error", "Unable to open file.")
_WinHttpCloseHandle($hOpen)
Return SetError(1)
EndIf
;главный цикл;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
While $Stop = 0
$Proxy = FileReadLine($hFileProxy)
If @error = -1 Then
ExitLoop
EndIf
$address = "208.78.70.70"
$zapros = "/?rnd1=" & Random(1, 65536) & "&rnd2=" & Random(1, 65536)
$CheckProxy = fZapros($hOpen, $zapros, $address, $Proxy)
If Not @error And TempIP($CheckProxy[2]) <> $MyPublicIP And Not @error Then
ConsoleWrite(TempIP($CheckProxy[2]) & @CRLF)
FileWriteLine($sFileGoodProxy, $Proxy)
Else
ConsoleWrite("Прокси " & $Proxy & " неподходит" & @TAB & $CheckProxy[0] & @CRLF)
EndIf
WEnd
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ConsoleWrite("Закончил" & @CRLF)
FileClose($hFileProxy)
_WinHttpCloseHandle($hOpen)
EndFunc ;==>ButtonStartClick
Func TempIP($strokaIP)
$strokaIP = StringTrimLeft($strokaIP, StringInStr($strokaIP, ":") + 1)
$strokaIP = StringTrimRight($strokaIP, StringLen($strokaIP) - StringInStr($strokaIP, "/") + 2)
$t_ip = StringSplit($strokaIP, '.')
If $t_ip[0] = 4 And StringIsDigit($t_ip[1]) And StringIsDigit($t_ip[2]) And StringIsDigit($t_ip[3]) And StringIsDigit($t_ip[4]) Then
Return $strokaIP
EndIf
Return SetError(1, 0, -1)
EndFunc ;==>TempIP
Func fZapros($hInternet, $pzapros, $paddress, $pProxy = "")
Dim $result[3]
If $pProxy <> "" Then
WinHttpSetProxy($hInternet, $pProxy)
If @error Then
$result[0] = "Error specifying proxy."
SetError(1)
Return $result
EndIf
EndIf
$hConnect = _WinHttpConnect($hInternet, $paddress)
If @error Then
$result[0] = "Error specifying the initial target server of an HTTP request."
SetError(2)
Return $result
EndIf
$h_openRequest = _WinHttpOpenRequest($hConnect, "GET", $pzapros)
If @error Then
$result[0] = "Error creating request handle."
_WinHttpCloseHandle($hConnect)
SetError(3)
Return $result
EndIf
_WinHttpSendRequest($h_openRequest)
If @error Then
$result[0] = "Error sending specified request."
_WinHttpCloseHandle($hConnect)
SetError(4)
Return $result
EndIf
_WinHttpReceiveResponse($h_openRequest)
If _WinHttpQueryDataAvailable($h_openRequest) = 1 Then
$header = _WinHttpQueryHeaders($h_openRequest)
Dim $sChunk = "", $sData = ""
While 1
$sChunk = _WinHttpReadData($h_openRequest)
If @error Then ExitLoop
$sData = $sData & $sChunk
WEnd
$result[1] = $header
$result[2] = $sData
Else
$result[0] = "Site is experiencing problems."
EndIf
_WinHttpCloseHandle($h_openRequest)
_WinHttpCloseHandle($hConnect)
If $result[0] = "Site is experiencing problems." Then SetError(5)
Return $result
EndFunc ;==>fZapros
Func WinHttpSetProxy($hInternet, $pProxy, $pProxyBypass = "<local>", $iAccessType = $WINHTTP_ACCESS_TYPE_NAMED_PROXY)
Local $tProxy = DllStructCreate("wchar[" & StringLen($pProxy) + 1 & "]")
DllStructSetData($tProxy, 1, $pProxy)
Local $tProxyBypass = DllStructCreate("wchar[" & StringLen($pProxyBypass) + 1 & "]")
DllStructSetData($tProxyBypass, 1, $pProxyBypass)
Local $tWINHTTP_PROXY_INFO = DllStructCreate("dword AccessType;" & _
"ptr Proxy;" & _
"ptr ProxyBypass")
DllStructSetData($tWINHTTP_PROXY_INFO, "AccessType", $iAccessType)
DllStructSetData($tWINHTTP_PROXY_INFO, "Proxy", DllStructGetPtr($tProxy))
DllStructSetData($tWINHTTP_PROXY_INFO, "ProxyBypass", DllStructGetPtr($tProxyBypass))
Local $a_iCall = DllCall("winhttp.dll", "int", "WinHttpSetOption", _
"hwnd", $hInternet, _
"dword", $WINHTTP_OPTION_PROXY, _
"ptr", DllStructGetPtr($tWINHTTP_PROXY_INFO), _
"dword", DllStructGetSize($tWINHTTP_PROXY_INFO))
If @error Or Not $a_iCall[0] Then
Return SetError(1, 0, 0)
EndIf
Return SetError(0, 0, 1)
EndFunc ;==>WinHttpSetProxy
Func Terminate()
ConsoleWrite("-СТОП-" & @CRLF)
$Stop = 1
EndFunc ;==>Terminate
Но он работает ужасно медленно, кроме того GUI перестаёт перерисовываться и реагировать на события если вызвать эту функцию. А всё из-за того что скрипт ждёт ответа в winHTTP , который будет в случае отсутствия прокси только спустя десятки секунд. Прочитал что winHTTP может посылать следующий запрос не дожидаясь ответа на предыдущий, но как это реализовать незнаю.
Используемые файлы:
WinHTTP.au3
WinHTTPConstants.au3
proxy.txt