How my software can catch/avoid "No carrier" response from QNetwork?
-
Hello!
I'm facing a problem when I need to treat some asynchronous requisitions from a service.
networkManager = new QNetworkAccessManager(this); QNetworkRequest request((QUrl (url))); request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json"); request.setRawHeader("Cache-Control", "no-cache"); reply = networkManager->post(request, QJsonDocument(body).toJson()); reply = networkManager->get(request); QObject::connect(networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*))); QObject::connect(reply, SIGNAL(error(QNetworkReply::NetworkError)), this, SLOT(replyError(QNetworkReply::NetworkError)));
Undesirable behavior occurs in situations where network access service is unstable. If the requisition fails, I can handle that and abort the reply. However, sometimes the long latency in response can result in a "long pooling" ways of QNetworkReply that waits for a long time, generating after x seconds the "No carrier" message.
It's very important to avoid this behavior, trying to catch "No carrier" or with the use of some approach to abort the reply.
The collateral effects are related to issues in QML interactions and the application can stop working in the worst case because several requests are made for each minute and QNetworkReply allocate each time more threads.
Mar 14 10:57:49 qt application[12911]: "No carrier" Mar 14 10:57:59 qt application[12911]: "No carrier" ... Mar 14 11:09:29 qt application[12911]: "No carrier" Mar 14 11:09:39 qt application[12911]: "No carrier" Mar 14 11:09:49 qt application[12911]: "No carrier" ... Mar 14 11:36:30 qt application[12911]: "No carrier"
How I could do to fix that?
-
I found an approach and it worked very well.
Set a timer to the reply is a way to deal with this question. A detailed discussion can be found here:
https://codereview.stackexchange.com/questions/30031/qnetworkreply-network-reply-timeout-helper
-
Qt 5.15.2
In my case it was network config manager that generated those "No carrier" messages. There's a plugin called qconnmanengine (qtbase/src/plugins/bearer/connman) which in case of wifi bearer periodically scans for wifi. You can simply reproduce this issue just by disable wifi technology (connmanctl disable wifi).
void QConnmanTechnologyInterface::scanReply(QDBusPendingCallWatcher *call) { QDBusPendingReply<> props_reply = *call; if (props_reply.isError()) { qDebug() << props_reply.error().message(); } Q_EMIT scanFinished(props_reply.isError()); call->deleteLater(); }