I was wondering how to cancel/abort a long running http request.
My investigation are, that the HttpClient is using curl (only checked the macOS sources yet). The main usage is, that one scene is for downloading some big data and I want to give the user the option to cancel the request. Also the Downloader doesn’t have any function to cancel a request (or I’m just unable to find that).
I am using cocos2d\cocos\network\CCDownloader.h
Unfortunately there is no abort…
This is what I am doing:
Init Downloader with some shorter timeout e.g.: 20s instead of default 45s
cocos2d::network::DownloaderHints{6, 20 /45/, “.tmp”}
Instead of one big file download many small files.
Wait for completed or failed event (onTaskError, onFileTaskSuccess)
In 99% you have good internet connection so you will download small file in 1-2 seconds or it will fail in few seconds (no internet or connection broken). Yes there is chance that user will have to wait 20 seconds …
Warning:
It is important to wait for onTaskError, onFileTaskSuccess
Stop is called in Downloader destructor. So in theory you can just stop/destroy object
But it does not stop downloading… thread will be running in background.
Next time when you run the same task two thread may write to the same file.
It seems like there is workaround for Downloader.stop and detached thread: instead of “.tmp” for tempFileNameSuffix you can use e.g. uuid. But I did not check it …
cocos2d::network::DownloaderHints{6, 20 /45/, “.tmp”}
With that idea, I would better to implement a download queue and only download the next file, if the user didn’t cancelled it. But this won’t help, if the file is large and it will download it completely before stopping the queue.
I can’t believe, that no one has such a feature request.
Okay, your checking in every progress update callback, if the download was canceled. The same behavior could maybe manually be implemented into the Downloader (onTaskProgress ??) from cocos, but I don’t unterstand, why this isn’t by default?
@tranthor I believe currently will no one win the million dollar.
Hi @mars3142
If you want to abort the request then We are handling this via below code into destructor, you just need to save pointer to HttpRequest and set nullptr to responseCallback and call release.
We have multiple request so we store into vec.
LoginMode::~LoginMode() {
for (int i = 0;i < (int)httpVec.size();i++)
{
httpVec.at(i)->setResponseCallback(nullptr);
httpVec.at(i)->release();
}
}
As far, as I understand the code from @smitpatel88 you didn’t call release directly after creation, but within the loop of the destructor. But the code didn’t cancel long running downloads, it just remove the callback, so the response will never be processed. Right.
Yes, I understand like you, I never “cancel” the request but if I set nullptr is equal to cancel it. So, it could solve the “cancel” problem. But I wonder how can I fill httpVec… hmm…
Thanks @smitpatel88 , that was the problem.
However, this alternative didn’t solve my problem.
My program crashes inside the for, at this line: httpVec.at(i)->setResponseCallback(nullptr);
Sometimes in the first element, sometimes in the second, etc. but it crashes.
Maybe because if the http response is in “action” i can’t set null there.
i’m requesting http info when I touch a button.
but when i touch the “Close” button i would like to cancel all requests. Because of this, i put this code in “close” button action:
for (int i = 0;i < (int)httpVec.size();i++)
{
httpVec.at(i)->setResponseCallback(nullptr);
httpVec.at(i)->release();
}