TimWoo
19th October 2015, 21:17
Hello all,
This is my first post on here. QtCentre and forum are a great source of information.
I have read through the forum and I found somewhat related posts, but not quite on the money, so I thought I'd give this a go, hoping I haven't missed any existing information on the subject.
As I state in the description, I’m having a problem with sending multiple network requests via the QnetworkAccessManager (QNAM) post method. The windows application runs as a QApplication.
The entire application consists of a client and a server, communicating through Http requests made by the client. The server only responds to requests and doesn't take any 'initiative'.
Sync::Sync(ConnectionInfo info) //info contains ip address and user auth
{
p = new SyncPrivate;
p->mManager = new QNetworkAccessManager(this);
connect(p->mManager, SIGNAL(authenticationRequired(QNetworkReply*,QAuth enticator*)),
SLOT(authenticate(QNetworkReply*, QAuthenticator*)));
p->mIpAddress = info.remoteIP();
switch(info.userLevel()) {
//UserAuth info here
}
p->mPassword = info.password();
}
void ControllerListEntry::on_actionStop_Monitoring_All_ Nodes_triggered()
{
if (mSync != 0)
return;
mSync = new Sync(mController->connectionInfo());
connect(mSync, SIGNAL(finished()), this, SLOT(stopMonitoringAllNodesFinished()));
foreach(Node *mNode, mController->getNodes()){ //Looping through all nodes
if(!mSync->setMonitoring(mNode, false))
break;
}
}
void ControllerListEntry::on_actionStart_Monitoring_All _Nodes_triggered()
{
if (mSync != 0)
return;
mSync = new Sync(mController->connectionInfo());
connect(mSync, SIGNAL(finished()), this, SLOT(startMonitoringAllNodesFinished()));
foreach(Node *mNode, mController->getNodes()){ //Looping through all nodes
if(!mSync->setMonitoring(mNode, true))
break;
}
}
//For each iteration of the previous loop, the following method is called:
bool Sync::setMonitoring(Node n, bool enabled)
{
QNetworkRequest req(QUrl("http://" + p->mIpAddress + "/rpc/set-monitoring"));
req.setAttribute(QNetworkRequest::HttpPipeliningAl lowedAttribute, QVariant(true));
QByteArray postReq = "nodename=" + encode(n->getName());
postReq += "&monitoring=" + QByteArray(enabled ? "true" : "false");
p->mBusy = true;
p->mReply = p->mManager->post(req, postReq);
connect(p->mReply, SIGNAL(finished()), SLOT(replyFinished()));
return true;
}
//For completeness sake
void Sync::replyFinished()
{
p->mReply->deleteLater();
p->mBusy = false;
// Check for errors.
if (p->mReply->error() != QNetworkReply::NoError) {
emit error(p->mReply->errorString()); //will call slot showing error message
return;
}
emit finished(); //ControllerListEntry will do some ui stuff
}
The problem is that requests are sent for only part of the Nodes in the Controller when above a certain number of Nodes. This certain number is somewhere around 8, this sound a bit vague and it is, but that's the nature of this problem. Sometimes 6 requests are sent, sometimes up to 11. Always more than 6 though.
I'm aware of the following line from the Qt Documentation for QNetworkAccessManager:
Note: QNetworkAccessManager queues the requests it receives. The number of requests executed in parallel is dependent on the protocol. Currently, for the HTTP protocol on desktop platforms, 6 requests are executed in parallel for one host/port combination.
That makes me expect that all the requests will be sent in blocks of 6, until no requests are left. Am I wrong in this?
Allowing HTTP Pipelining or disabling it doesn't seem to make any difference in the result.
Sometimes I get the following in the application output: QCoreApplication::postEvent: Unexpected null receiver. Would this happen when not receiving a network reply?
I can confirm:
• The setMonitoring code finished every time for every Node.
• Only for part of the (1 - very small amount) Nodes a reply is caught by the replyFinished Slot
â—‹ Using Wireshark:
§ Http Replies are actually seen on the network
§ Not always an Http reply for every request
• It is always the requests for the last n Nodes that don't get sent. No "gaps" in between.
• Qt version: Qt 4.7.4.
For 18 Nodes this is what happens on the network on Http level between client and server.
11458
I hope someone can provide some ideas on the matter.
Many thanks in advance,
Tim
This is my first post on here. QtCentre and forum are a great source of information.
I have read through the forum and I found somewhat related posts, but not quite on the money, so I thought I'd give this a go, hoping I haven't missed any existing information on the subject.
As I state in the description, I’m having a problem with sending multiple network requests via the QnetworkAccessManager (QNAM) post method. The windows application runs as a QApplication.
The entire application consists of a client and a server, communicating through Http requests made by the client. The server only responds to requests and doesn't take any 'initiative'.
Sync::Sync(ConnectionInfo info) //info contains ip address and user auth
{
p = new SyncPrivate;
p->mManager = new QNetworkAccessManager(this);
connect(p->mManager, SIGNAL(authenticationRequired(QNetworkReply*,QAuth enticator*)),
SLOT(authenticate(QNetworkReply*, QAuthenticator*)));
p->mIpAddress = info.remoteIP();
switch(info.userLevel()) {
//UserAuth info here
}
p->mPassword = info.password();
}
void ControllerListEntry::on_actionStop_Monitoring_All_ Nodes_triggered()
{
if (mSync != 0)
return;
mSync = new Sync(mController->connectionInfo());
connect(mSync, SIGNAL(finished()), this, SLOT(stopMonitoringAllNodesFinished()));
foreach(Node *mNode, mController->getNodes()){ //Looping through all nodes
if(!mSync->setMonitoring(mNode, false))
break;
}
}
void ControllerListEntry::on_actionStart_Monitoring_All _Nodes_triggered()
{
if (mSync != 0)
return;
mSync = new Sync(mController->connectionInfo());
connect(mSync, SIGNAL(finished()), this, SLOT(startMonitoringAllNodesFinished()));
foreach(Node *mNode, mController->getNodes()){ //Looping through all nodes
if(!mSync->setMonitoring(mNode, true))
break;
}
}
//For each iteration of the previous loop, the following method is called:
bool Sync::setMonitoring(Node n, bool enabled)
{
QNetworkRequest req(QUrl("http://" + p->mIpAddress + "/rpc/set-monitoring"));
req.setAttribute(QNetworkRequest::HttpPipeliningAl lowedAttribute, QVariant(true));
QByteArray postReq = "nodename=" + encode(n->getName());
postReq += "&monitoring=" + QByteArray(enabled ? "true" : "false");
p->mBusy = true;
p->mReply = p->mManager->post(req, postReq);
connect(p->mReply, SIGNAL(finished()), SLOT(replyFinished()));
return true;
}
//For completeness sake
void Sync::replyFinished()
{
p->mReply->deleteLater();
p->mBusy = false;
// Check for errors.
if (p->mReply->error() != QNetworkReply::NoError) {
emit error(p->mReply->errorString()); //will call slot showing error message
return;
}
emit finished(); //ControllerListEntry will do some ui stuff
}
The problem is that requests are sent for only part of the Nodes in the Controller when above a certain number of Nodes. This certain number is somewhere around 8, this sound a bit vague and it is, but that's the nature of this problem. Sometimes 6 requests are sent, sometimes up to 11. Always more than 6 though.
I'm aware of the following line from the Qt Documentation for QNetworkAccessManager:
Note: QNetworkAccessManager queues the requests it receives. The number of requests executed in parallel is dependent on the protocol. Currently, for the HTTP protocol on desktop platforms, 6 requests are executed in parallel for one host/port combination.
That makes me expect that all the requests will be sent in blocks of 6, until no requests are left. Am I wrong in this?
Allowing HTTP Pipelining or disabling it doesn't seem to make any difference in the result.
Sometimes I get the following in the application output: QCoreApplication::postEvent: Unexpected null receiver. Would this happen when not receiving a network reply?
I can confirm:
• The setMonitoring code finished every time for every Node.
• Only for part of the (1 - very small amount) Nodes a reply is caught by the replyFinished Slot
â—‹ Using Wireshark:
§ Http Replies are actually seen on the network
§ Not always an Http reply for every request
• It is always the requests for the last n Nodes that don't get sent. No "gaps" in between.
• Qt version: Qt 4.7.4.
For 18 Nodes this is what happens on the network on Http level between client and server.
11458
I hope someone can provide some ideas on the matter.
Many thanks in advance,
Tim