我的 Delphi 12 项目正在使用 NetHTTPClient 组件下载 2GB 的文件。
下载过程快速进行且没有中断,但 60 秒后(大约下载的三分之一)出现异常,提示连接超时。
我将三个时间设置(ResponseTimeout、SendTimeout 和 ConnectionTimeout)从默认值 60,000(一分钟)调整为 600,000,这样就解决了这个问题,因为下载大约需要三分钟。
我怎样才能让它只在连接真正超时时引发连接超时?
我的 Delphi 12 项目正在使用 NetHTTPClient 组件下载 2GB 的文件。
下载过程快速进行且没有中断,但 60 秒后(大约下载的三分之一)出现异常,提示连接超时。
我将三个时间设置(ResponseTimeout、SendTimeout 和 ConnectionTimeout)从默认值 60,000(一分钟)调整为 600,000,这样就解决了这个问题,因为下载大约需要三分钟。
我怎样才能让它只在连接真正超时时引发连接超时?
在大多数平台上,这
ResponseTimeout
是允许完成响应的最长时间。默认值为 1 分钟。如果将其设置为 10 分钟,则可以提供足够的时间来完成下载。该
ResponseTimeout
行为取决于您的代码在哪个平台上运行。在 Windows 上,
TNetHTTPClient
使用WinHTTP
,并且 MSDN 文档对该WinHTTPSetTimeouts()
功能进行了如下说明:在 Linux 上,
TNetHTTPClient
使用,并且 Curl 文档对/选项Curl
说明如下:CURLOPT_TIMEOUT
CURLOPT_TIMEOUT_MS
如果
ResponseTimeout
小于0,TNetHTTPClient
则将CURLOPT_TIMEOUT_MS
选项设置为0,即无限。在 MacOS 和 iOS 上,
TNetHTTPClient
使用URLSession
,并且 Apple 文档对该属性的说明如下URLSessionConfiguration.timeoutIntervalForResource
:如果
ResponseTimeout
小于 0,TNetHTTPClient
则将设置timeoutIntervalForResource
为 1 年。在 Android 上,
TNetHTTPClient
使用URLConnection
,并且 Android Java 文档对该URLConnection.setReadTimeout()
方法的说明如下:这意味着
ResponseTimeout
超时时间实际上是按字节计算的,而不是像其他平台那样按最大响应时间计算。请参阅:理解 URLConnection.setReadTimeout()。因此,回答您的问题:如果您在所有平台上将
ResponseTimeout
超时时间设置为,则将无限期地(或接近无限期地)等待响应完成。但是,由于您预计下载将在 3 分钟内完成,因此设置 10 分钟的超时时间是合理的。<= 0
TNetHTTPClient
类似的规则适用于
ConnectTimeout
属性(连接到服务器的最大时间)和SendTimeout
属性(发送请求的最大时间) - 只是目前TNetHTTPClient
似乎尚未针对 Android 和 Linux 实现,仅针对 Windows 和 MacOS/iOS。SendTimeout
TNetHTTPClient
有一个事件OnReceiveData
,可以用来了解服务器是否仍在定期发送数据。为此,您可以在发起请求时记录当前时间,然后从该OnReceiveData
事件中再次保存该时间并让传输继续进行。此外,还可以添加一个 TTimer 来定期检查已保存的时间与当前时间,以确定在此期间是否收到了数据。查看文档。