PDA

View Full Version : QNetworkAccessManager - finished signal (when emitted)



RavensAngel
15th March 2016, 14:39
I have a REST-service which i access using an HTTP POST. Using soap ui, i get timings like 30 ms. When using QNetworkaccessmanager (connecting the finished signal, direct connection) i get 230 ms.

I used wireshark to check what is going on...

What i see is that both ways are sending the same messages:
•TCP SYN (time: 15.9528600)
•TCP SYN, ACK (time: 15.9536980)
•ACK (time: 15.9537440)
•HTTP POST (time: 15.9549770)
•HTTP REPLY (time: 15.9998710)
•TCP ACK (time: 16.1998570) --> the time difference between the last HTTP reply and the ack is +/- 200 ms...

The question is, is the finished signal emitted after the TCP ack in QNetworkAccessManager and can i force the signal to be emitted faster? Is it normal it waits to ack the reply before sending the finished signal? If so, is there another signal i can use to get the reply sooner?

Or am I doing it wrong?

Part of code:
_am = new QNetworkAccessManager();
connect( _am, SIGNAL( finished( QNetworkReply* ) ), this, SLOT( _requestFinished( QNetworkReply* ) ), Qt::DirectConnection );
...
QNetworkRequest request( _requestData.url );
request.setHeader( QNetworkRequest::ContentTypeHeader,"application/json" );
_elapsed.restart();
_reply = _am->post( request, _requestData.data );


I time using QElapsedTimer just before doing the post and within the _requestFinished slot i take the elapsed time and output it.
I always see 200+ ms...

Any help? Or ideas?

Thanks in advance.

anda_skoa
15th March 2016, 15:33
The question is, is the finished signal emitted after the TCP ack in QNetworkAccessManager and can i force the signal to be emitted faster?

My guess is that the socket is only closed after the FIN ACK and that is used to determine that there is really nothing else to do anymore.
I.e. using the socket "finished" rather than any HTTP protocol "end".

But you could look into the code to check.



If so, is there another signal i can use to get the reply sooner?

Well, you could process the data as it arrives.

Cheers,
_

RavensAngel
15th March 2016, 16:25
But i timed the readyRead signal on the _reply, which i assume would be needed in case of "process as arrived". But the timings remain ... the readyRead is called 200+ ms and the finished is only emitted 1 ms later. (timed with the same elapsed timer).

So it seems the implementation of QNetworkReply is slow ... as when implemented using c# for example, doing the same, the timings relfect the ones with soapui...
I don't know whether i can boost this request-reply mechanism... it's weird.

RavensAngel
16th March 2016, 15:58
I found one if the issues. I seems that the HTTP POST is put in 2 TCP packages.
The Nagle algorithm seems to be causing certain delay because of this. I disabled the Nagle algorithm on the server side, which already gave me some performance boost.

But there is still a difference on the latency between the C# client and the Qt client.
In wireshark you can see that C# implementation is sending an extra continue message ... maybe it's related to that. I don't know yet...

ChrisW67
16th March 2016, 21:46
What is certain is that the QNetworkAccessManager will not issue the finished() until some time after the respective QNetworkReply does, and that readyRead() may be issued multiple times before that.