商店的客户显示器连接到局域网上的192.168.1.68。它使用长轮询来使用http POST接收显示数据。
它显示发送的数据,但HttpSendRequest需要5次发送才能返回。我将超时设置为60毫秒,重试次数设置为1,但在HttpSendRequest完成之前仍然需要5秒。
如果超时值更大,HttpSendRequest将等待更长的时间。
为什么HttpSendRequest不能等待少于5秒?
如何在发送数据后立即终止调用,以便单线程应用程序可以继续。命令
curl -d "@duedata.json" -H "Content-Type: application/json; charset=utf-8" --max-time 2 -X POST http://192.168.1.92:8082/poll-command
耗时2秒,并在PCU中显示数据。数据发送到显示器需要1.2秒。
FUNCTION HTTPGetEx
LPARAMETERS tcPage, tcBuffer, tnBufferSize, tcHeaders, tcFileName, lpost
DECLARE INTEGER HttpOpenRequest ;
IN WININET.DLL ;
INTEGER hHTTPHandle,;
STRING lpzReqMethod,;
STRING lpzPage,;
STRING lpzVersion,;
STRING lpzReferer,;
STRING lpzAcceptTypes,;
INTEGER dwFlags,;
INTEGER dwContextw
hHTTPResult=HttpOpenRequest(THIS.hhttpsession,;
Icase(VARTYPE(lpost)='C', lpost, lpost or tnPostSize > 0, "POST","GET"),;
tcPage,;
NULL,NULL,NULL,;
INTERNET_FLAG_RELOAD + ;
IIF(THIS.lsecurelink,INTERNET_FLAG_SECURE,0) + ;
this.nHTTPServiceFlags,0)
*** Apply timeout to the HTTP connection handle
THIS.wininetsettimeout(THIS.nConnectTimeOut,hHTTPResult)
THIS.wininetsettimeout(THIS.nConnectTimeOut)
THIS.hhttpsession=hHTTPResult
DECLARE INTEGER HttpSendRequest ;
IN WININET.DLL ;
INTEGER hHTTPHandle,;
STRING lpzHeaders,;
INTEGER cbHeaders,;
STRING lpzPost,;
INTEGER cbPost
dwTimeoutSecs = 60
llRetVal=InternetSetOption(hHTTPResult,;
INTERNET_OPTION_RECEIVE_TIMEOUT,;
@dwTimeoutSecs,4)
llRetVal=InternetSetOption(hHTTPResult,;
INTERNET_OPTION_SEND_TIMEOUT,;
@dwTimeoutSecs,4)
dwTimeoutSecs=1 &&// Retry only 1 time
llRetVal=InternetSetOption( hHTTPResult,;
INTERNET_OPTION_CONNECT_RETRIES,;
@dwTimeoutSecs,4)
? 'Before HttpSendRequest'
* Todo: why HttpSendRequest takes 5 seconds ?
lnRetval=HttpSendRequest(hHTTPResult,tcHeaders,LEN(tcHeaders),lcPostBuffer,tnPostSize)
? 'After HttpSendRequest'
使用winhttprequest:
检查https://learn.microsoft.com/en-us/windows/win32/winhttp/iwinhttprequest-settimeouts
Clear
owinhttp = Create('winhttp.winhttprequest.5.1')
owinhttph = Create("winhttpH")
Eventhandler(owinhttp,owinhttph)
url = 'https://stackoverflow.com/questions/66857697/how-to-terminate-connection-immediately-on-long-polling'
Try
With owinhttp
* resolveTimeout,connectTimeout,sendTimeout,receiveTimeout:
.setTimeOuts(2000,30000,30000,60000)
.Open('GET',url,.F.)
.setrequestheader('Connection','keep-alive')
.Send()
Endwith
Catch
Aerror(ae)
If ae(1,1) # 1429
Display Memory Like ae
Endif
Endtry
*****************************************************
Define Class winhttph As Session OlePublic
*****************************************************
Implements iwinhttprequestevents In winhttp.winhttprequest.5.1
bytesrec = 0
cData = ''
*-------------------------------------------------------------------------------------
Procedure iwinhttprequestevents_onresponsedataavailable(Data As variant) As void
*-------------------------------------------------------------------------------------
This.bytesrec = This.bytesrec+Len(Data)
This.cData = This.cData+Data
? 'Bytes received:',This.bytesrec
? Strconv(Data,11)
If This.bytesrec > 2000
owinhttp.abort()
Strtofile(Ttoc(Datetime())+Chr(13)+This.cData,'test.txt')
Modify File test.txt Nowait
Endif
*--------------------------------------------------------------------
Procedure iwinhttprequestevents_onresponsestart(Status As Number, contenttype As String) As void
*--------------------------------------------------------------------
*--------------------------------------------------------------------
Procedure iwinhttprequestevents_onerror(errornumber As Number, errordescription As String) As void
*--------------------------------------------------------------------
if errorNumber # -2147024890
? 'ERROR',errornumber,errordescription,'url:'+url
endif
*--------------------------------------------------------------------
Procedure iwinhttprequestevents_onresponsefinished() As void
*--------------------------------------------------------------------
********************************************
Enddefine
********************************************