让 WinHttp.WaitForResponse() 超时等待超过 30 秒

供新手入门和老手参考的教程和相关资料,包括中文帮助

Moderators: tmplinshi, arcticir

Post Reply
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

让 WinHttp.WaitForResponse() 超时等待超过 30 秒

Post by tmplinshi » 08 Aug 2015, 23:18

默认情况下,WinHttp.WaitForResponse() 最多只能等待 30 秒,也就是说...
  • WinHttp.WaitForResponse() ; 最多等待 30 秒,而不是无限期等待。
  • WinHttp.WaitForResponse(60) ; 最多等待 30 秒,而不是 60 秒。
要让 WinHttp.WaitForResponse() 超时等待超过 30 秒,需要先调用 WinHttp.SetTimeouts(解析超时, 连接超时, 发送超时, 接收超时)

参数的超时单位是毫秒。比如把超时等待修改为 120 秒:
WinHttp.SetTimeouts(0, 60000, 30000, 120000)
前面三个值 0, 60000, 30000 是默认值。更多详细说明见 IWinHttpRequest::SetTimeouts method

Code: Select all

whr := ComObjCreate("WinHttp.WinHttpRequest.5.1")
whr.Open("GET", URL, true)
whr.SetTimeouts(0, 60000, 30000, 120000)
whr.Send()
whr.WaitForResponse(90)

tuzi
Posts: 223
Joined: 27 Apr 2016, 23:40

Re: 让 WinHttp.WaitForResponse() 超时等待超过 30 秒

Post by tuzi » 12 Nov 2021, 01:16

通过分析使用不同参数组合,访问连接不稳定及完全无法连接的网站而得出的日志,可以得到以下结论。WaitForResponse 就像是所有超时的总和 SetTimeouts 则是总和中的每个子项。
超时既可能因为总和,也可能因为某个子项,还可能因为一个原因未知的,时间总是固定为21秒的条件触发。
所以综合来看,设置超时参数时最好将 解析超时设为0(避免内存溢出) 然后将 连接超时、发送超时、接收超时、总超时 都设置为一样的。
这样当超时时间小于21秒时,一定会以设置的超时为准。
而当超时时间大于21秒时,则会随机的在21秒或设定值时返回。

以下是测试代码。

Code: Select all

loop, 40
{
  st:=A_TickCount
  
  ComObjError(0)
  wr := ComObjCreate("WinHttp.WinHttpRequest.5.1")
  ; 解析超时=0 连接超时=60000 发送超时=30000 接收超时=11000
  wr.SetTimeouts(0, 60000, 30000, 11000)
  wr.Open("GET", "https://raw.githubusercontent.com/telppa/PaddleOCR-AutoHotkey/main/PaddleOCR/Dll/opencv_world452.dll", true)
  ; wr.Open("GET", "https://www.google.com", true)
  wr.Send()
  ; 总超时=25000
  wr.WaitForResponse(25)
  
  FileAppend, % A_TickCount-st "|" wr.Status() "`n", 超时.log
}
ExitApp
以下是不同参数,访问不同网址的超时日志。

Code: Select all

访问 github.com                                                        访问 google.com
参数 0 60 30 11 25       0 8 12 16 4             0 8 12 16 25          参数 0 60 30 11 25    0 8 12 16 4          0 8 12 16 25
-----------------------------------------------------------------------------------------------------------------------
25063|200                4015|200                20015|                25047|                4047|                8016|
25031|200                4016|                   8000|                 25015|                4015|                8000|
17922|                   4047|                   19797|                25032|                4016|                8000|
21047|                   4015|                   8203|                 25015|                4016|                8000|
21047|                   4047|                   8000|                 25016|                4015|                8000|
21046|                   4016|                   25016|200             25016|                4016|                8000|
25032|200                4016|                   10984|                25015|                4016|                8015|
21047|                   4015|                   8000|                 21047|                4015|                7985|
25015|200                4016|                   8000|                 25016|                4016|                8000|
25016|200                4015|                   8000|                 25015|                4015|                8000|
25062|200                4016|                   8000|                 25016|                4016|                8000|
11688|                   4016|                   8000|                 25062|                4016|                8000|
12015|                   4015|                   8000|                 25016|                4015|                8000|
21047|                   4016|                   8000|                 25031|                4016|                8000|
21032|                   4016|                   8000|                 25016|                4016|                8000|
21031|                   4015|                   8000|                 25047|                4015|                8000|
21031|                   4016|                   8000|                 25047|                4016|                8000|
21047|                   4015|                   8000|                 25015|                4015|                8000|
21031|                   4016|                   8000|                 25016|                4016|                8000|
21047|                   4016|                   20000|                25016|                4016|                8000|
21016|                   4047|                   20000|                25015|                4015|                8000|
25015|200                4015|                   8000|                 25016|                4016|                8000|
10703|                   4016|                   8000|                 25015|                4016|                8000|
25032|200                4015|                   8000|                 25016|                4015|                8000|
10968|                   4016|                   8000|                 25016|                4016|                8000|
21047|                   4016|                   20000|                25015|                4015|                8000|
21032|                   4015|                   8000|                 25016|                4016|                8000|
21062|                   4016|                   8000|                 25016|                4016|                8000|
21047|                   4016|                   8000|                 25015|                4015|                8000|
21031|                   4015|                   8000|                 25016|                4016|                8000|
21047|                   4016|                   8000|                 25015|                4016|                8000|
21719|                   4015|                   8000|                 21016|                4015|                8000|
21047|                   4016|                   8000|                 25016|                4016|                8000|
14953|                   4016|                   8000|                 25015|                4015|                8000|
12000|                   4015|                   8000|                 21032|                4016|                8000|
21031|                   4016|                   8000|                 21046|                4016|                8000|
21047|                   4016|                   8000|                 21047|                4015|                8000|
21047|                   4015|200                8000|                 21032|                4016|                8000|
21015|                   4016|                   8000|                 25031|                4016|                8000|
21032|                   4015|                   8000|                 25015|                4015|                8000|

zhang
Posts: 6
Joined: 29 Oct 2022, 20:08

Re: 让 WinHttp.WaitForResponse() 超时等待超过 30 秒

Post by zhang » 21 Nov 2022, 22:05

感谢分享,解决了我的问题,如果要下载大文件,WaitForResponse通常都会超时,另外给出用WinHttp下载二进制流并存储为文件的方法,以防有人需要 :)
本例子仅作示例,不可直接运行,若要运行,请手动替换GET请求的网址

Code: Select all

;网址:="https://"
whr.Open("GET",网址,true)
;如果是大文件,文件下载时间会比较长,要增加Response的等待时间
whr.SetTimeouts(0, 60000, 30000, 120000)
whr.SetRequestHeader("Authorization",token)
whr.Send()
whr.WaitForResponse(210)
;如果下载的文件是二进制流,那么响应头会附带Content-Type: application/octet-stream;charset=UTF-8
tmp:=whr.GetResponseHeader("Content-Type")
if !instr(tmp,"octet-stream")
{
    msgbox 请求的格式不正确,数据不是二进制流
    exitapp
}
;如果下载的内容是文件,那么通常响应头会附带Content-disposition: attachment; filename=<文件名>.<后缀名>
tmp:=whr.GetResponseHeader("Content-disposition")
if !instr(tmp,"filename")
{
    msgbox 请求的格式不正确,当前请求返回的不是文件类型
    exitapp
}
文件名:=Strsplit(tmp,"filename")[2]
;使用adodb.stream对象处理二进制流
stm:=ComObjCreate("adodb.stream")
stm.Type:=1 ;以二进制模式读取
stm.open()
stm.Write(whr.ResponseBody) ;这里要使用ResponseBody而不是ResponseText
;指定文件保存位置
stm.SaveToFile("D:\" . 文件名,2)
stm.flush() 
stm.Close()

Post Reply

Return to “教程资料”