_lastUsedServerIndex(0),
_lastPingTime(0),
+ _maxPingCount(3),
+ _pingCount(0),
// TODO make autowho configurable (possibly per-network)
_autoWhoEnabled(true),
_autoReconnectCount = 0; // prohibiting auto reconnect
}
disablePingTimeout();
+ _msgQueue.clear();
IrcUser *me_ = me();
if(me_) {
_previousConnectionAttemptFailed = true;
qWarning() << qPrintable(tr("Could not connect to %1 (%2)").arg(networkName(), socket.errorString()));
emit connectionError(socket.errorString());
- emit displayMsg(Message::Error, BufferInfo::StatusBuffer, "", tr("Connection failure: %1").arg(socket.errorString()));
+ displayMsg(Message::Error, BufferInfo::StatusBuffer, "", tr("Connection failure: %1").arg(socket.errorString()));
emitConnectionError(socket.errorString());
if(socket.state() < QAbstractSocket::ConnectedState) {
socketDisconnected();
}
// TokenBucket to avoid sending too much at once
- _messagesPerSecond = 1;
+ _messageDelay = 2200; // this seems to be a safe value (2.2 seconds delay)
_burstSize = 5;
- _tokenBucket = 5; // init with a full bucket
- _tokenBucketTimer.start(_messagesPerSecond * 1000);
+ _tokenBucket = _burstSize; // init with a full bucket
+ _tokenBucketTimer.start(_messageDelay);
if(!server.password.isEmpty()) {
putRawLine(serverEncode(QString("PASS %1").arg(server.password)));
void CoreNetwork::socketDisconnected() {
disablePingTimeout();
+ _msgQueue.clear();
_autoWhoCycleTimer.stop();
_autoWhoTimer.stop();
IrcUser *me_ = me();
if(me_) {
foreach(QString channel, me_->channels())
- emit displayMsg(Message::Quit, BufferInfo::ChannelBuffer, channel, _quitReason, me_->hostmask());
+ displayMsg(Message::Quit, BufferInfo::ChannelBuffer, channel, _quitReason, me_->hostmask());
}
setConnected(false);
Core::setNetworkConnected(userId(), networkId(), false);
} else if(_autoReconnectCount != 0) {
setConnectionState(Network::Reconnecting);
- if(_autoReconnectCount == autoReconnectRetries())
+ if(_autoReconnectCount == -1 || _autoReconnectCount == autoReconnectRetries())
doAutoReconnect(); // first try is immediate
else
_autoReconnectTimer.start();
if(useAutoReconnect()) {
// reset counter
- _autoReconnectCount = autoReconnectRetries();
+ _autoReconnectCount = unlimitedReconnectRetries() ? -1 : autoReconnectRetries();
}
// restore away state
qWarning() << "CoreNetwork::doAutoReconnect(): Cannot reconnect while not being disconnected!";
return;
}
- if(_autoReconnectCount > 0)
- _autoReconnectCount--;
+ if(_autoReconnectCount > 0 || _autoReconnectCount == -1)
+ _autoReconnectCount--; // -2 means we delay the next reconnect
connectToIrc(true);
}
void CoreNetwork::sendPing() {
uint now = QDateTime::currentDateTime().toTime_t();
- if(_lastPingTime != 0 && now - _lastPingTime <= (uint)(_pingTimer.interval() / 1000) + 1) {
+ if(_pingCount != 0) {
+ qDebug() << "UserId:" << userId() << "Network:" << networkName() << "missed" << _pingCount << "pings."
+ << "BA:" << socket.bytesAvailable() << "BTW:" << socket.bytesToWrite();
+ }
+ if(_pingCount >= _maxPingCount && now - _lastPingTime <= (uint)(_pingTimer.interval() / 1000) + 1) {
// the second check compares the actual elapsed time since the last ping and the pingTimer interval
// if the interval is shorter then the actual elapsed time it means that this thread was somehow blocked
// and unable to even handle a ping answer. So we ignore those misses.
- disconnectFromIrc(false, QString("No Ping reply in %1 seconds.").arg(_pingTimer.interval() / 1000), true /* withReconnect */);
+ disconnectFromIrc(false, QString("No Ping reply in %1 seconds.").arg(_maxPingCount * _pingTimer.interval() / 1000), true /* withReconnect */);
} else {
_lastPingTime = now;
+ _pingCount++;
userInputHandler()->handlePing(BufferInfo(), QString());
}
}