PDA

View Full Version : QNetworkReply: how to know when data is sent?



mentalmushroom
23rd June 2011, 08:42
I am using QNetworkAccessManager:post method for sending data to a server. Waiting for reply may take a long, but I don't really need it: I just need to know when the data is sent. Is it possible?

For example, I need to wait until logout command is sent before destroying QNetworkAccessManager.

Santosh Reddy
23rd June 2011, 08:46
You can send a logout command in a slot connected to this signal

void QNetworkAccessManager::finished ( QNetworkReply * reply ) ;

mentalmushroom
23rd June 2011, 10:20
Are you sure it will be enough time to send all the data before QNetworkAccessManager is destroyed? Perhaps I need to delete it right after exiting from the slot connected to QNetworkAccessManager::finished.
What if I don't even have anything connected to finished signal? Perhaps I simply need to send data and quit, something like this:


QNetworkAccessManager manager;
manager.post(...);
// need to wait until data is sent here
return;

wysota
23rd June 2011, 10:32
QNetworkAccessManager API doesn't allow you to trace when it is finished posting data. Either wait for the response to come or don't use QNAM.

mentalmushroom
23rd June 2011, 10:43
Ok, what could be a good alternative for that purpose?

wysota
23rd June 2011, 10:57
QHttp should work fine. It has a dataSendProgress() signal.

mentalmushroom
23rd June 2011, 11:43
Ok, i thought to use it from the very beginning, I didn't just because I read the following in the Qt documentation: "This class is obsolete. It is provided to keep old source code working. We strongly advise against using it in new code."

wysota
23rd June 2011, 12:24
Yes, that's true but your requirement is somewhat different from what people use HTTP for in their apps. I don't know why you don't want to wait for the server's response -- you might get a 404 or 500 or some other fault. I think it's worth knowing if your request went to /dev/null or not.

mentalmushroom
23rd June 2011, 12:53
I may want to upload some data or send logout. Sometimes it takes a several seconds (depending on connection, network problems etc). In my application it is more important to proceed quickly than know whether the data was uploaded or not. I don't care much how successful was logout sent to some third party server, but I want my app to be closed quickly, so users won't need to wait until slow server responds.

wysota
23rd June 2011, 14:24
So why do you want to send the logout at all if you don't care if it works or not?

mentalmushroom
23rd June 2011, 16:15
I send logout because it is better to send than not to send (third party server recommends to send it). Also I upload some data that may be useful, but if it fails it is not critical. Moreover if logout fails in most cases I can't do anything with that, so result can be only logged somewhere and it is not that important for users. But as long as it doesn't make my application inconvenient to users I think it is better to call logout and upload all the data that may be useful.

wysota
23rd June 2011, 17:10
Then don't wait for anything, send the data and start closing your app. With a bit of luck, the request will go through. If not then you don't care anyway... If you do care, then wait a predefined amount of time for a response and if you don't get it during this period, abandon the request and close your app.

mentalmushroom
24th June 2011, 08:02
Well, eventually I came to the same approach. I can afford it to wait for let's say 1 second, the only bad side is that waiting for data sent in most cases would take less time, but with this approach I still have to wait 1 second that is for the worst case. My question: is there any place where I can ask to add this feature? To my mind having dataSent signal would be useful.

wysota
24th June 2011, 08:35
Qt is open-source, add the feature yourself. It should be just a couple lines of code.

Santosh Reddy
24th June 2011, 08:44
You can delete QNetworkAccessManager, when things are done, don't need to wait, only thing is create QNetworkAccessManager on heap, here is a snippet


MyObject::sendLastPost()
{
QNetworkAccessManager * manager = new QNetworkAccessManager;
connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(logout()));
post(request, data); //Send Data, for which reply is not cared for, and also ignore post fails
}

void MyObject::logout(void) //slot, don't call direclty
{
QNetworkAccessManager * manager = dynamic_cast<QNetworkAccessManager *>(sender());
if(manager)
{
disconnect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(logout()));
connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(deleteLater()));
post(request, data); //Send Logout data
}
}

Just call sendLastPost(), rest should be taken care, including deletion.

wysota
24th June 2011, 09:01
He wants to quit the app immediately so this won't do. And furthermore some servers will abandon the request if the remote site terminates connection so I think all this approach of posting data without waiting for response has little chance of working.

Santosh Reddy
24th June 2011, 09:17
Ok, I missed the Application exit requirement:)


I send logout because it is better to send than not to send (third party server recommends to send it). Also I upload some data that may be useful, but if it fails it is not critical. Moreover if logout fails in most cases I can't do anything with that, so result can be only logged somewhere and it is not that important for users. But as long as it doesn't make my application inconvenient to users I think it is better to call logout and upload all the data that may be useful.

Looks like the kind of closing sequence

1. App wants to exit
2. then log into server
3. upload usage data (any useful, but not critical data)
4. logout
5. exit app

OP can also connect QNetworkAccessManage::finished() to QCoreApplication::quit (), then hide() the MainWindow (all the MainWindows), this should not make application inconvenient to users

wysota
24th June 2011, 09:22
It wouldn't be inconvenient for me if the window was there saying it uploads data :) I prefer that to a hidden window with the application looking like frozen. But then everyone has his own inconveniences...