mirror of
https://github.com/qt/qtmqtt.git
synced 2026-10-25 16:16:26 +00:00
Fix reconnecting after transport error
In case a connection fails due to a transport error, the client must be able to try to reconnect. Hence, reset the error state when connectToHost is called. Furthermore the socket needs to be re-created if it has been instantiated by QMqttClient previously. Task-number: QTBUG-65726 Change-Id: Id54e5f91a8ca4d0c7be6f51f1ad79e090c681584 Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
This commit is contained in:
parent
50a203b7eb
commit
68fe97befd
@ -419,6 +419,7 @@ void QMqttClient::connectToHost(bool encrypted, const QString &sslPeerName)
|
||||
d->setStateAndError(Disconnected, TransportInvalid);
|
||||
return;
|
||||
}
|
||||
d->m_error = QMqttClient::NoError; // Fresh reconnect, unset error
|
||||
d->setStateAndError(Connecting);
|
||||
|
||||
if (d->m_cleanSession)
|
||||
|
||||
@ -87,8 +87,12 @@ bool QMqttConnection::ensureTransport(bool createSecureIfNeeded)
|
||||
{
|
||||
qCDebug(lcMqttConnection) << Q_FUNC_INFO << m_transport;
|
||||
|
||||
if (m_transport)
|
||||
return true;
|
||||
if (m_transport) {
|
||||
if (m_ownTransport)
|
||||
delete m_transport;
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
// We are asked to create a transport layer
|
||||
if (m_clientPrivate->m_hostname.isEmpty() || m_clientPrivate->m_port == 0) {
|
||||
|
||||
@ -29,6 +29,7 @@
|
||||
#include "broker_connection.h"
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include <QtNetwork/QTcpServer>
|
||||
#include <QtTest/QtTest>
|
||||
#include <QtTest/QSignalSpy>
|
||||
#include <QtMqtt/QMqttClient>
|
||||
@ -55,6 +56,7 @@ private Q_SLOTS:
|
||||
void subscribeLongTopic();
|
||||
void dataIncludingZero();
|
||||
void publishLongTopic();
|
||||
void reconnect_QTBUG65726();
|
||||
private:
|
||||
QProcess m_brokerProcess;
|
||||
QString m_testBroker;
|
||||
@ -388,6 +390,63 @@ void Tst_QMqttClient::publishLongTopic()
|
||||
QCOMPARE(pub, -1);
|
||||
}
|
||||
|
||||
class FakeServer : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
FakeServer() {
|
||||
server = new QTcpServer();
|
||||
connect(server, &QTcpServer::newConnection, this, &FakeServer::createSocket);
|
||||
server->listen(QHostAddress::Any, 5726);
|
||||
}
|
||||
public slots:
|
||||
void createSocket() {
|
||||
socket = server->nextPendingConnection();
|
||||
connect(socket, &QTcpSocket::readyRead, this, &FakeServer::connectionRequested);
|
||||
}
|
||||
|
||||
void connectionRequested() {
|
||||
// We assume it is always a connect statement, so no verification is done
|
||||
socket->readAll();
|
||||
QByteArray response;
|
||||
response += 0x20;
|
||||
response += quint8(2); // Payload size
|
||||
if (!connectionSuccess) {
|
||||
response += quint8(255); // Causes ProtocolViolation
|
||||
response += quint8(13);
|
||||
} else {
|
||||
response += char(0); // ackFlags
|
||||
response += char(0); // result
|
||||
}
|
||||
qDebug() << "Fake server response:" << connectionSuccess;
|
||||
socket->write(response);
|
||||
}
|
||||
public:
|
||||
QTcpServer *server;
|
||||
QTcpSocket *socket;
|
||||
bool connectionSuccess{false};
|
||||
};
|
||||
|
||||
void Tst_QMqttClient::reconnect_QTBUG65726()
|
||||
{
|
||||
FakeServer server;
|
||||
|
||||
QMqttClient client;
|
||||
client.setClientId(QLatin1String("bugclient"));
|
||||
client.setHostname(QLatin1String("localhost"));
|
||||
client.setPort(5726);
|
||||
|
||||
client.connectToHost();
|
||||
QTRY_COMPARE(client.state(), QMqttClient::Disconnected);
|
||||
QTRY_COMPARE(client.error(), QMqttClient::ProtocolViolation);
|
||||
|
||||
server.connectionSuccess = true;
|
||||
|
||||
client.connectToHost();
|
||||
QTRY_COMPARE(client.state(), QMqttClient::Connected);
|
||||
QTRY_COMPARE(client.error(), QMqttClient::NoError);
|
||||
}
|
||||
|
||||
QTEST_MAIN(Tst_QMqttClient)
|
||||
|
||||
#include "tst_qmqttclient.moc"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user