是否可以为QNetworkReply
设置超时,因此很长一段时间没有来自服务器的回复,它可能会发出finished()
信号?
答案 0 :(得分:4)
如果不使用计时器,这是不可能的,但您不必显式编写计时器代码。该功能可以整齐地打包到静态函数中,该函数就像超时是回复的可设置属性一样 - 参见下面的示例。
有两个问题:
如何处理正在进行的请求的超时。
如何确定网络请求是否已开始处理。 this question。
一个简单的超时处理程序可以如下实现(从this answer派生)。该代码可在Qt 4和Qt 5中移植。
您可以在abort
-ing超时请求(默认值)或close
-ing之间进行选择。前者立即释放网络资源,后者允许请求完成但丢弃收到的任何数据,并且对上传请求非常有用。
class ReplyTimeout : public QObject {
Q_OBJECT
QBasicTimer m_timer;
HandleMethod m_method;
public:
enum HandleMethod { Abort, Close };
QReplyTimeout(QNetworkReply* reply, const int timeout, HandleMethod method = Abort) :
QObject(reply), m_method(method)
{
Q_ASSERT(reply);
if (reply && reply->isRunning()) {
m_timer.start(timeout, this);
connect(reply, &QNetworkReply::finished, this, &QObject::deleteLater);
}
static void set(QNetworkReply* reply, const int timeout, HandleMethod method = Abort) {
new ReplyTimeout(reply, timeout, method);
}
protected:
void timerEvent(QTimerEvent * ev) {
if (!m_timer.isActive() || ev->timerId() != m_timer.timerId())
return;
auto reply = static_cast<QNetworkReply*>(parent());
if (reply->isRunning()) {
if (m_method == Close)
reply->close();
else if (m_method == Abort)
reply->abort();
m_timer.stop();
}
};
使用:
QNetworkAccessManager networkAccessManger;
QNetworkReply* reply =
networkAccessManger.get(QNetworkRequest(QUrl("https://www.google.com")));
ReplyTimeout::set(reply, 100);
答案 1 :(得分:0)
对于Qt 5.15,它应该是一个内置功能-刚刚发现它已经修复了10年的旧错误:) https://codereview.qt-project.org/c/qt/qtbase/+/278064