是否可以设置超时QNetworkReply,因此很长一段时间没有来自服务器的回复,它可以发出finished()信号?
不使用计时器是不可能的,但是您不必显式编写计时器代码。该功能可以整齐地打包到一个静态函数中,该函数的作用就像超时是回复的可设置属性一样(请参见下面的示例)。
有两个问题:
如何处理正在进行的请求的超时。
如何确定网络请求是否已开始处理。这个问题在解决这个问题。
可以如下实现一个简单的超时处理程序(从此答案派生)。该代码可跨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();
}
};
Run Code Online (Sandbox Code Playgroud)
使用:
QNetworkAccessManager networkAccessManger;
QNetworkReply* reply =
networkAccessManger.get(QNetworkRequest(QUrl("https://www.google.com")));
ReplyTimeout::set(reply, 100);
Run Code Online (Sandbox Code Playgroud)