diff options
| author | Jeremy Lainé <jeremy.laine@m4x.org> | 2010-03-10 11:06:53 +0000 |
|---|---|---|
| committer | Jeremy Lainé <jeremy.laine@m4x.org> | 2010-03-10 11:06:53 +0000 |
| commit | b4442cdcf163d96bbf0d893eddf59a5bee0c64b6 (patch) | |
| tree | 1c29ca36d041ab3bcf3e49569bff696de4d6f4b8 | |
| parent | 617dd2f07a30203fd885a5bad041ada73f9f8db0 (diff) | |
| download | qxmpp-b4442cdcf163d96bbf0d893eddf59a5bee0c64b6.tar.gz | |
add support for keep alive
| -rw-r--r-- | source/QXmppClient.h | 1 | ||||
| -rw-r--r-- | source/QXmppReconnectionManager.cpp | 5 | ||||
| -rw-r--r-- | source/QXmppStream.cpp | 63 | ||||
| -rw-r--r-- | source/QXmppStream.h | 8 |
4 files changed, 77 insertions, 0 deletions
diff --git a/source/QXmppClient.h b/source/QXmppClient.h index 70f5297e..d2539c25 100644 --- a/source/QXmppClient.h +++ b/source/QXmppClient.h @@ -74,6 +74,7 @@ public: enum Error { SocketError, ///< Error due to TCP socket + KeepAliveError, ///< Error due to no response to a keep alive XmppStreamError, ///< Error due to XML stream XmppStanzaError ///< Error due to stanza }; diff --git a/source/QXmppReconnectionManager.cpp b/source/QXmppReconnectionManager.cpp index 8c0fbaa8..65557811 100644 --- a/source/QXmppReconnectionManager.cpp +++ b/source/QXmppReconnectionManager.cpp @@ -62,6 +62,11 @@ void QXmppReconnectionManager::error(QXmppClient::Error error) m_timer.start(time*1000); emit reconnectingIn(time); } + else if (m_client && error == QXmppClient::KeepAliveError) + { + // if we got a keepalive error, reconnect in one second + m_timer.start(1000); + } } int QXmppReconnectionManager::getNextReconnectingInTime() diff --git a/source/QXmppStream.cpp b/source/QXmppStream.cpp index 0fa9c24b..bbe3e35c 100644 --- a/source/QXmppStream.cpp +++ b/source/QXmppStream.cpp @@ -54,6 +54,7 @@ #include <QRegExp> #include <QHostAddress> #include <QXmlStreamWriter> +#include <QTimer> static const QByteArray streamRootElementStart = "<?xml version=\"1.0\"?><stream:stream xmlns:stream=\"http://etherx.jabber.org/streams\" version=\"1.0\" xmlns=\"jabber:client\" xml:lang=\"en\" xmlns:xml=\"http://www.w3.org/XML/1998/namespace\">\n"; static const QByteArray streamRootElementEnd = "</stream:stream>"; @@ -155,6 +156,22 @@ QXmppStream::QXmppStream(QXmppClient* client) check = QObject::connect(this, SIGNAL(streamInitiationIqReceived(const QXmppStreamInitiationIq&)), &m_transferManager, SLOT(streamInitiationIqReceived(const QXmppStreamInitiationIq&))); Q_ASSERT(check); + + // XEP-0199: XMPP Ping + m_pingTimer = new QTimer(); + check = QObject::connect(m_pingTimer, SIGNAL(timeout()), this, SLOT(pingSend())); + Q_ASSERT(check); + + m_timeoutTimer = new QTimer(); + m_timeoutTimer->setSingleShot(true); + check = QObject::connect(m_timeoutTimer, SIGNAL(timeout()), this, SLOT(pingTimeout())); + Q_ASSERT(check); + + check = QObject::connect(this, SIGNAL(xmppConnected()), this, SLOT(pingStart())); + Q_ASSERT(check); + + check = QObject::connect(this, SIGNAL(disconnected()), this, SLOT(pingStop())); + Q_ASSERT(check); } QXmppStream::~QXmppStream() @@ -307,6 +324,10 @@ void QXmppStream::parser(const QByteArray& data) QString ns = nodeRecv.namespaceURI(); debug("Namespace: " + ns + " Tag: " + nodeRecv.tagName() ); + + // if we receive any kind of data, stop the timeout timer + m_timeoutTimer->stop(); + if(m_client->handleStreamElement(nodeRecv)) { // already handled by client, do nothing @@ -1115,6 +1136,48 @@ void QXmppStream::processRosterIq(const QXmppRosterIq& rosterIq) } } +void QXmppStream::pingStart() +{ + const int interval = getConfiguration().keepAliveInterval(); + // start ping timer + if (interval > 0) + { + m_pingTimer->setInterval(interval * 1000); + m_pingTimer->start(); + } +} + +void QXmppStream::pingStop() +{ + // stop all timers + m_pingTimer->stop(); + m_timeoutTimer->stop(); +} + +void QXmppStream::pingSend() +{ + // send ping packet + QXmppPingIq ping; + ping.setFrom(getConfiguration().jid()); + ping.setTo(getConfiguration().domain()); + sendPacket(ping); + + // start timeout timer + const int timeout = getConfiguration().keepAliveTimeout(); + if (timeout > 0) + { + m_timeoutTimer->setInterval(timeout * 1000); + m_timeoutTimer->start(); + } +} + +void QXmppStream::pingTimeout() +{ + warning("Ping timeout"); + disconnect(); + emit error(QXmppClient::KeepAliveError); +} + QAbstractSocket::SocketError QXmppStream::getSocketError() { return m_socketError; diff --git a/source/QXmppStream.h b/source/QXmppStream.h index f3e90e45..493553b2 100644 --- a/source/QXmppStream.h +++ b/source/QXmppStream.h @@ -35,6 +35,7 @@ #include "QXmppTransferManager.h" class QDomElement; +class QTimer; class QXmppRoster; class QXmppClient; @@ -121,6 +122,11 @@ private slots: void socketError(QAbstractSocket::SocketError); void socketSslErrors(const QList<QSslError>&); + void pingStart(); + void pingStop(); + void pingSend(); + void pingTimeout(); + private: QXmppClient* m_client; // reverse pointer QXmppRoster m_roster; @@ -135,6 +141,8 @@ private: QString m_nonSASLAuthId; QString m_XMPPVersion; QXmppClient::StreamError m_xmppStreamError; + QTimer *m_pingTimer; + QTimer *m_timeoutTimer; // m_xmppStanzaError; QXmppArchiveManager m_archiveManager; |
