2016-05-25 33 views

答えて

3

タイマーを使用しないとできませんが、明示的にタイマーコードを書く必要はありません。この機能は、タイムアウトが応答の設定可能なプロパティであるかのように動作する静的関数にきれいにパッケージ化できます。以下の例を参照してください。

二つの問題があります。進行中のリクエストに応じてタイムアウトを処理する方法を

  1. が。

  2. ネットワーク要求が処理を開始したかどうかを判断する方法。この問題は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); 
関連する問題