From 32c550d8f25392616de13fe761285ac13cf5e0d9 Mon Sep 17 00:00:00 2001 From: Marcus Eggenberger Date: Wed, 11 Feb 2009 15:27:09 +0100 Subject: [PATCH] fixes #500 - improved detection of disconnects from irc --- src/core/corenetwork.cpp | 54 ++++++++++++++++++++++------------- src/core/corenetwork.h | 6 +++- src/core/ircserverhandler.cpp | 2 ++ 3 files changed, 41 insertions(+), 21 deletions(-) diff --git a/src/core/corenetwork.cpp b/src/core/corenetwork.cpp index b9e82e44..3dc0cc27 100644 --- a/src/core/corenetwork.cpp +++ b/src/core/corenetwork.cpp @@ -40,6 +40,8 @@ CoreNetwork::CoreNetwork(const NetworkId &networkid, CoreSession *session) _previousConnectionAttemptFailed(false), _lastUsedServerIndex(0), + _gotPong(true), + // TODO make autowho configurable (possibly per-network) _autoWhoEnabled(true), _autoWhoInterval(90), @@ -50,7 +52,7 @@ CoreNetwork::CoreNetwork(const NetworkId &networkid, CoreSession *session) _socketCloseTimer.setSingleShot(true); connect(&_socketCloseTimer, SIGNAL(timeout()), this, SLOT(socketCloseTimeout())); - _pingTimer.setInterval(60000); + _pingTimer.setInterval(30000); connect(&_pingTimer, SIGNAL(timeout()), this, SLOT(sendPing())); _autoWhoTimer.setInterval(_autoWhoDelay * 1000); @@ -181,10 +183,12 @@ void CoreNetwork::connectToIrc(bool reconnecting) { #endif } -void CoreNetwork::disconnectFromIrc(bool requested, const QString &reason) { +void CoreNetwork::disconnectFromIrc(bool requested, const QString &reason, bool withReconnect) { _quitRequested = requested; // see socketDisconnected(); - _autoReconnectTimer.stop(); - _autoReconnectCount = 0; // prohibiting auto reconnect + if(!withReconnect) { + _autoReconnectTimer.stop(); + _autoReconnectCount = 0; // prohibiting auto reconnect + } IrcUser *me_ = me(); if(me_) { @@ -195,24 +199,26 @@ void CoreNetwork::disconnectFromIrc(bool requested, const QString &reason) { Core::setUserModes(userId(), networkId(), me_->userModes()); } + if(reason.isEmpty() && identityPtr()) + _quitReason = identityPtr()->quitReason(); + else + _quitReason = reason; + displayMsg(Message::Server, BufferInfo::StatusBuffer, "", tr("Disconnecting.")); - if(socket.state() == QAbstractSocket::UnconnectedState) { - socketDisconnected(); - } else if(socket.state() < QAbstractSocket::ConnectedState || !requested) { - // we might be in a state waiting for a timeout... - // or (!requested) this is a core shutdown... - // in both cases we don't really care... set a disconnected state - socket.close(); + switch(socket.state()) { + case QAbstractSocket::UnconnectedState: socketDisconnected(); - } else { - // quit gracefully if it's user requested quit - if(reason.isEmpty() && identityPtr()) - _quitReason = identityPtr()->quitReason(); - else - _quitReason = reason; + break; + case QAbstractSocket::ConnectedState: userInputHandler()->issueQuit(_quitReason); - // the irc server has 10 seconds to close the socket - _socketCloseTimer.start(10000); + default: + if(!requested) { + socket.close(); + socketDisconnected(); + } else { + // the irc server has 10 seconds to close the socket + _socketCloseTimer.start(10000); + } } } @@ -333,6 +339,8 @@ void CoreNetwork::socketInitialized() { void CoreNetwork::socketDisconnected() { _pingTimer.stop(); + resetPong(); + _autoWhoCycleTimer.stop(); _autoWhoTimer.stop(); _autoWhoQueue.clear(); @@ -410,6 +418,7 @@ void CoreNetwork::networkInitialized() { sendPerform(); + resetPong(); _pingTimer.start(); if(_autoWhoEnabled) { @@ -506,7 +515,12 @@ void CoreNetwork::doAutoReconnect() { } void CoreNetwork::sendPing() { - userInputHandler()->handlePing(BufferInfo(), QString()); + if(!gotPong()) { + disconnectFromIrc(false, QString("No Ping reply in %1 seconds.").arg(_pingTimer.interval() / 1000), true /* withReconnect */); + } else { + _gotPong = false; + userInputHandler()->handlePing(BufferInfo(), QString()); + } } void CoreNetwork::sendAutoWho() { diff --git a/src/core/corenetwork.h b/src/core/corenetwork.h index 8303b252..f50717b0 100644 --- a/src/core/corenetwork.h +++ b/src/core/corenetwork.h @@ -91,7 +91,7 @@ public slots: virtual void setAutoReconnectRetries(quint16); void connectToIrc(bool reconnecting = false); - void disconnectFromIrc(bool requested = true, const QString &reason = QString()); + void disconnectFromIrc(bool requested = true, const QString &reason = QString(), bool withReconnect = false); void userInput(BufferInfo bufferInfo, QString msg); void putRawLine(QByteArray input); @@ -106,6 +106,9 @@ public slots: Server usedServer() const; + inline void resetPong() { _gotPong = true; } + inline bool gotPong() { return _gotPong; } + signals: void recvRawServerMsg(QString); void displayStatusMsg(QString); @@ -173,6 +176,7 @@ private: int _lastUsedServerIndex; QTimer _pingTimer; + bool _gotPong; bool _autoWhoEnabled; QStringList _autoWhoQueue; diff --git a/src/core/ircserverhandler.cpp b/src/core/ircserverhandler.cpp index 5c60b3b8..bcdcf446 100644 --- a/src/core/ircserverhandler.cpp +++ b/src/core/ircserverhandler.cpp @@ -385,6 +385,8 @@ void IrcServerHandler::handlePong(const QString &prefix, const QList if(params.count() < 2) return; + network()->resetPong(); + QString timestamp = serverDecode(params[1]); QTime sendTime = QTime::fromString(timestamp, "hh:mm:ss.zzz"); if(!sendTime.isValid()) { -- 2.20.1