IMA with asynchronous ReceiveHTTPMemory
Posted: Wed Oct 28, 2015 4:11 pm
With asynchronous, its very important to use the ReceiveHTTPMemory() function in the right way, otherwise there are happen sporadic IMA's and
its hard to debug the real error reason..
Unfortunately, the help example for HTTPProgress() shows only a one time asynchronous download and not what to do,
if the download fails or aborted..
Please correct me if I'm wrong: Contrary to what the example suggests, it is very important to finish every download with FinishHTTP()
even if it is canceled or failed.
To reproduce the problem, here is the the extended example:
its hard to debug the real error reason..
Unfortunately, the help example for HTTPProgress() shows only a one time asynchronous download and not what to do,
if the download fails or aborted..
Code: Select all
; PB help example for HTTPProgress()
InitNetwork()
Download = ReceiveHTTPMemory("http://www.purebasic.com/download/OgreAssimpConverter.zip", #PB_HTTP_Asynchronous)
If Download
Repeat
Progress = HTTPProgress(Download)
Select Progress
Case #PB_Http_Success
*Buffer = FinishHTTP(Download)
Debug "Download finished (size: " + MemorySize(*Buffer) + ")"
FreeMemory(*Buffer)
End
Case #PB_Http_Failed
Debug "Download failed"
End
Case #PB_Http_Aborted
Debug "Download aborted"
End
Default
Debug "Current download: " + Progress
EndSelect
Delay(500) ; Don't stole the whole CPU
ForEver
Else
Debug "Download error"
EndIf
even if it is canceled or failed.
Code: Select all
Procedure.S ReceiveHTTPMemory_(Url.S, TimeOut.I = 0); No TimeOut = Synchron, TimeOut > 0 = Asynch
Protected *mem, Result.S, Connection.I
If TimeOut = 0
*mem = ReceiveHTTPMemory(Url)
If *mem <> 0
Result = PeekS(*mem, MemorySize(*mem), #PB_Ascii)
FreeMemory(*mem)
EndIf
Else
TimeOut = ElapsedMilliseconds() + TimeOut
Connection = ReceiveHTTPMemory(Url, #PB_HTTP_Asynchronous)
If Connection
Repeat
Delay(100)
Select HTTPProgress(Connection)
Case #PB_Http_Success
Result = "[success]"
Break
Case #PB_Http_Failed, #PB_Http_Aborted
Result = "[failed]"
Break
EndSelect
If ElapsedMilliseconds() > TimeOut
Result = "[timeout]"
AbortHTTP(Connection)
Delay(100) ; give it some extra time
Break
EndIf
ForEver
*mem = FinishHTTP(Connection)
If *mem <> 0
Result = PeekS(*mem, MemorySize(*mem), #PB_Ascii)
FreeMemory(*mem)
EndIf
Else
Result = "[no connection]"
EndIf
EndIf
ProcedureReturn Result
EndProcedure
To reproduce the problem, here is the the extended example:
Code: Select all
InitNetwork()
Procedure Provoke_IMA()
Download = ReceiveHTTPMemory("http://www.purebasic.com", #PB_HTTP_Asynchronous)
If Download
Repeat
progress = HTTPProgress(Download)
Select progress
Case #PB_Http_Success
*Buffer = FinishHTTP(Download)
Debug "Download finished (size: " + MemorySize(*Buffer) + ")"
FreeMemory(*Buffer)
Break
Case #PB_Http_Failed
Debug "Download failed"
Break
Case #PB_Http_Aborted
Debug "Download aborted"
Break
Default
;Debug "Current download: " + progress
EndSelect
Delay(1)
ForEver
Else
Debug "Download error"
EndIf
EndProcedure
For a = 1 To 20
Provoke_IMA()
Next