From abb6912c11dc322718724eb11e70617d8428b6f5 Mon Sep 17 00:00:00 2001 From: Kurt Pattyn Date: Thu, 13 Feb 2014 22:00:27 +0100 Subject: Fix multiple emission of received signals Task-number: QTBUG-36762 Change-Id: I239bdd06252fb90056a687ace8540bb91b0055a1 Reviewed-by: Kurt Pattyn --- src/websockets/qwebsocket_p.cpp | 2 +- tests/auto/qwebsocket/tst_qwebsocket.cpp | 216 +++++++++++++++++++++++++++++++ 2 files changed, 217 insertions(+), 1 deletion(-) diff --git a/src/websockets/qwebsocket_p.cpp b/src/websockets/qwebsocket_p.cpp index d54337f..338e581 100644 --- a/src/websockets/qwebsocket_p.cpp +++ b/src/websockets/qwebsocket_p.cpp @@ -575,7 +575,7 @@ void QWebSocketPrivate::releaseConnections(const QTcpSocket *pTcpSocket) { if (Q_LIKELY(pTcpSocket)) pTcpSocket->disconnect(pTcpSocket); - m_dataProcessor.disconnect(&m_dataProcessor); + m_dataProcessor.disconnect(); } /*! diff --git a/tests/auto/qwebsocket/tst_qwebsocket.cpp b/tests/auto/qwebsocket/tst_qwebsocket.cpp index 51cfc08..bf93e37 100644 --- a/tests/auto/qwebsocket/tst_qwebsocket.cpp +++ b/tests/auto/qwebsocket/tst_qwebsocket.cpp @@ -41,12 +41,92 @@ #include #include #include +#include #include QT_USE_NAMESPACE Q_DECLARE_METATYPE(QWebSocketProtocol::Version) +class EchoServer : public QObject +{ + Q_OBJECT +public: + explicit EchoServer(QObject *parent = Q_NULLPTR); + ~EchoServer(); + + QHostAddress hostAddress() const { return m_pWebSocketServer->serverAddress(); } + quint16 port() const { return m_pWebSocketServer->serverPort(); } + +Q_SIGNALS: + void closed(); + +private Q_SLOTS: + void onNewConnection(); + void processTextMessage(QString message); + void processBinaryMessage(QByteArray message); + void socketDisconnected(); + +private: + QWebSocketServer *m_pWebSocketServer; + QList m_clients; +}; + +EchoServer::EchoServer(QObject *parent) : + QObject(parent), + m_pWebSocketServer(new QWebSocketServer(QStringLiteral("Echo Server"), + QWebSocketServer::NonSecureMode, this)), + m_clients() +{ + if (m_pWebSocketServer->listen()) { + connect(m_pWebSocketServer, &QWebSocketServer::newConnection, + this, &EchoServer::onNewConnection); + connect(m_pWebSocketServer, &QWebSocketServer::closed, this, &EchoServer::closed); + } +} + +EchoServer::~EchoServer() +{ + m_pWebSocketServer->close(); + qDeleteAll(m_clients.begin(), m_clients.end()); +} + +void EchoServer::onNewConnection() +{ + QWebSocket *pSocket = m_pWebSocketServer->nextPendingConnection(); + + connect(pSocket, &QWebSocket::textMessageReceived, this, &EchoServer::processTextMessage); + connect(pSocket, &QWebSocket::binaryMessageReceived, this, &EchoServer::processBinaryMessage); + connect(pSocket, &QWebSocket::disconnected, this, &EchoServer::socketDisconnected); + + m_clients << pSocket; +} + +void EchoServer::processTextMessage(QString message) +{ + QWebSocket *pClient = qobject_cast(sender()); + if (pClient) { + pClient->sendTextMessage(message); + } +} + +void EchoServer::processBinaryMessage(QByteArray message) +{ + QWebSocket *pClient = qobject_cast(sender()); + if (pClient) { + pClient->sendBinaryMessage(message); + } +} + +void EchoServer::socketDisconnected() +{ + QWebSocket *pClient = qobject_cast(sender()); + if (pClient) { + m_clients.removeAll(pClient); + pClient->deleteLater(); + } +} + class tst_QWebSocket : public QObject { Q_OBJECT @@ -64,6 +144,8 @@ private Q_SLOTS: void tst_invalidOpen_data(); void tst_invalidOpen(); void tst_invalidOrigin(); + void tst_sendTextMessage(); + void tst_sendBinaryMessage(); }; tst_QWebSocket::tst_QWebSocket() @@ -323,6 +405,140 @@ void tst_QWebSocket::tst_invalidOrigin() QCOMPARE(bytesWrittenSpy.count(), 0); } +void tst_QWebSocket::tst_sendTextMessage() +{ + EchoServer echoServer; + + QWebSocket socket; + QSignalSpy socketConnectedSpy(&socket, SIGNAL(connected())); + QSignalSpy textMessageReceived(&socket, SIGNAL(textMessageReceived(QString))); + QSignalSpy textFrameReceived(&socket, SIGNAL(textFrameReceived(QString,bool))); + QSignalSpy binaryMessageReceived(&socket, SIGNAL(binaryMessageReceived(QByteArray))); + QSignalSpy binaryFrameReceived(&socket, SIGNAL(binaryFrameReceived(QByteArray,bool))); + + socket.open(QUrl(QStringLiteral("ws://") + echoServer.hostAddress().toString() + + QStringLiteral(":") + QString::number(echoServer.port()))); + + if (socketConnectedSpy.count() == 0) + QVERIFY(socketConnectedSpy.wait(500)); + QCOMPARE(socket.state(), QAbstractSocket::ConnectedState); + + socket.sendTextMessage(QStringLiteral("Hello world!")); + + QVERIFY(textMessageReceived.wait(500)); + QCOMPARE(textMessageReceived.count(), 1); + QCOMPARE(binaryMessageReceived.count(), 0); + QCOMPARE(binaryFrameReceived.count(), 0); + QList arguments = textMessageReceived.takeFirst(); + QString messageReceived = arguments.at(0).toString(); + QCOMPARE(messageReceived, QStringLiteral("Hello world!")); + + QCOMPARE(textFrameReceived.count(), 1); + arguments = textFrameReceived.takeFirst(); + QString frameReceived = arguments.at(0).toString(); + bool isLastFrame = arguments.at(1).toBool(); + QCOMPARE(frameReceived, QStringLiteral("Hello world!")); + QVERIFY(isLastFrame); + + socket.close(); + + //QTBUG-36762: QWebSocket emits multiplied signals when socket was reopened + socketConnectedSpy.clear(); + textMessageReceived.clear(); + textFrameReceived.clear(); + + socket.open(QUrl(QStringLiteral("ws://") + echoServer.hostAddress().toString() + + QStringLiteral(":") + QString::number(echoServer.port()))); + + if (socketConnectedSpy.count() == 0) + QVERIFY(socketConnectedSpy.wait(500)); + QCOMPARE(socket.state(), QAbstractSocket::ConnectedState); + + socket.sendTextMessage(QStringLiteral("Hello world!")); + + QVERIFY(textMessageReceived.wait(500)); + QCOMPARE(textMessageReceived.count(), 1); + QCOMPARE(binaryMessageReceived.count(), 0); + QCOMPARE(binaryFrameReceived.count(), 0); + arguments = textMessageReceived.takeFirst(); + messageReceived = arguments.at(0).toString(); + QCOMPARE(messageReceived, QStringLiteral("Hello world!")); + + QCOMPARE(textFrameReceived.count(), 1); + arguments = textFrameReceived.takeFirst(); + frameReceived = arguments.at(0).toString(); + isLastFrame = arguments.at(1).toBool(); + QCOMPARE(frameReceived, QStringLiteral("Hello world!")); + QVERIFY(isLastFrame); +} + +void tst_QWebSocket::tst_sendBinaryMessage() +{ + EchoServer echoServer; + + QWebSocket socket; + QSignalSpy socketConnectedSpy(&socket, SIGNAL(connected())); + QSignalSpy textMessageReceived(&socket, SIGNAL(textMessageReceived(QString))); + QSignalSpy textFrameReceived(&socket, SIGNAL(textFrameReceived(QString,bool))); + QSignalSpy binaryMessageReceived(&socket, SIGNAL(binaryMessageReceived(QByteArray))); + QSignalSpy binaryFrameReceived(&socket, SIGNAL(binaryFrameReceived(QByteArray,bool))); + + socket.open(QUrl(QStringLiteral("ws://") + echoServer.hostAddress().toString() + + QStringLiteral(":") + QString::number(echoServer.port()))); + + if (socketConnectedSpy.count() == 0) + QVERIFY(socketConnectedSpy.wait(500)); + QCOMPARE(socket.state(), QAbstractSocket::ConnectedState); + + socket.sendBinaryMessage(QByteArrayLiteral("Hello world!")); + + QVERIFY(binaryMessageReceived.wait(500)); + QCOMPARE(textMessageReceived.count(), 0); + QCOMPARE(textFrameReceived.count(), 0); + QCOMPARE(binaryMessageReceived.count(), 1); + QList arguments = binaryMessageReceived.takeFirst(); + QByteArray messageReceived = arguments.at(0).toByteArray(); + QCOMPARE(messageReceived, QByteArrayLiteral("Hello world!")); + + QCOMPARE(binaryFrameReceived.count(), 1); + arguments = binaryFrameReceived.takeFirst(); + QByteArray frameReceived = arguments.at(0).toByteArray(); + bool isLastFrame = arguments.at(1).toBool(); + QCOMPARE(frameReceived, QByteArrayLiteral("Hello world!")); + QVERIFY(isLastFrame); + + socket.close(); + + //QTBUG-36762: QWebSocket emits multiplied signals when socket was reopened + socketConnectedSpy.clear(); + binaryMessageReceived.clear(); + binaryFrameReceived.clear(); + + socket.open(QUrl(QStringLiteral("ws://") + echoServer.hostAddress().toString() + + QStringLiteral(":") + QString::number(echoServer.port()))); + + if (socketConnectedSpy.count() == 0) + QVERIFY(socketConnectedSpy.wait(500)); + QCOMPARE(socket.state(), QAbstractSocket::ConnectedState); + + socket.sendBinaryMessage(QByteArrayLiteral("Hello world!")); + + QVERIFY(binaryMessageReceived.wait(500)); + QCOMPARE(textMessageReceived.count(), 0); + QCOMPARE(textFrameReceived.count(), 0); + QCOMPARE(binaryMessageReceived.count(), 1); + arguments = binaryMessageReceived.takeFirst(); + messageReceived = arguments.at(0).toByteArray(); + QCOMPARE(messageReceived, QByteArrayLiteral("Hello world!")); + + QCOMPARE(binaryFrameReceived.count(), 1); + arguments = binaryFrameReceived.takeFirst(); + frameReceived = arguments.at(0).toByteArray(); + isLastFrame = arguments.at(1).toBool(); + QCOMPARE(frameReceived, QByteArrayLiteral("Hello world!")); + QVERIFY(isLastFrame); +} + QTEST_MAIN(tst_QWebSocket) #include "tst_qwebsocket.moc" -- cgit v1.2.3