summaryrefslogtreecommitdiff
path: root/src/webchannel
diff options
context:
space:
mode:
authorMilian Wolff <milian.wolff@kdab.com>2014-03-21 16:15:47 +0100
committerPierre Rossi <pierre.rossi@gmail.com>2014-07-04 12:37:29 +0200
commit856dc072acb649be03e02ac64c81015d3f2675c2 (patch)
tree649985d553d6ea92360a66ca291af91c1114596e /src/webchannel
parent9f78e0985d2f4fdc2588be57c5f25afdd59c6365 (diff)
downloadqtwebchannel-856dc072acb649be03e02ac64c81015d3f2675c2.tar.gz
Refactor code to use QWebChannelAbstractTransport and QtWebSockets.
This is a quite big changeset, but necessary to get the roadmap implemented that was discussed at QtCS. With this patchset landed, the QWebChannel does not depend on QtWebKit anymore, not even for the tests. Rather, we will introduce the dependency in the other way (i.e. QtWebKit will optionally use QtWebChannel if available). For the pure Qt/C++ use-case, we ship a utility implementation of a QWebChannelAbstractTransport that uses a QWebSocket for the server-client communication. This way, we can get rid of the custom WebSocket implementation. The tests are refactored to run the qwebchannel.js code directly inside QML. Integration tests for QtWebKit/QtWebEngine as well as examples will be added to these repositories. Change-Id: Icc1c1c5918ec46e31d5070937c14c4ca25a3e2d6 Reviewed-by: Pierre Rossi <pierre.rossi@gmail.com>
Diffstat (limited to 'src/webchannel')
-rw-r--r--src/webchannel/qmetaobjectpublisher.cpp10
-rw-r--r--src/webchannel/qmetaobjectpublisher_p.h15
-rw-r--r--src/webchannel/qwebchannel.cpp32
-rw-r--r--src/webchannel/qwebchannel.h8
-rw-r--r--src/webchannel/qwebchannel.js30
-rw-r--r--src/webchannel/qwebchannel_p.h7
-rw-r--r--src/webchannel/qwebchannelabstracttransport.cpp58
-rw-r--r--src/webchannel/qwebchannelabstracttransport.h (renamed from src/webchannel/qwebsockettransport_p.h)51
-rw-r--r--src/webchannel/qwebchannelwebsockettransport.cpp (renamed from src/webchannel/qwebchanneltransportinterface.h)63
-rw-r--r--src/webchannel/qwebchannelwebsockettransport.h (renamed from src/webchannel/qwebsockettransport.h)39
-rw-r--r--src/webchannel/qwebsockettransport.cpp212
-rw-r--r--src/webchannel/webchannel.pro8
12 files changed, 177 insertions, 356 deletions
diff --git a/src/webchannel/qmetaobjectpublisher.cpp b/src/webchannel/qmetaobjectpublisher.cpp
index 2914714..096bf7b 100644
--- a/src/webchannel/qmetaobjectpublisher.cpp
+++ b/src/webchannel/qmetaobjectpublisher.cpp
@@ -42,6 +42,7 @@
#include "qmetaobjectpublisher_p.h"
#include "qwebchannel.h"
#include "qwebchannel_p.h"
+#include "qwebchannelabstracttransport.h"
#include <QEvent>
#include <QJsonDocument>
@@ -394,7 +395,7 @@ QByteArray QMetaObjectPublisher::invokeMethod(QObject *const object, const int m
void QMetaObjectPublisher::signalEmitted(const QObject *object, const int signalIndex, const QVariantList &arguments)
{
- if (!webChannel) {
+ if (!webChannel || webChannel->d->transports.isEmpty()) {
return;
}
if (!signalToPropertyMap.value(object).contains(signalIndex)) {
@@ -544,15 +545,18 @@ QByteArray QMetaObjectPublisher::handleRequest(const QJsonObject &message)
return QByteArray();
}
-void QMetaObjectPublisher::handleMessage(const QString &message, QWebChannelTransportInterface *transport, int clientId)
+void QMetaObjectPublisher::handleMessage(const QString &message)
{
+ QWebChannelAbstractTransport *transport = qobject_cast<QWebChannelAbstractTransport*>(sender());
+ Q_ASSERT(transport);
+
const QJsonDocument doc = QJsonDocument::fromJson(message.toUtf8());
if (!doc.isObject()) {
return;
}
const QByteArray &response = handleRequest(doc.object());
if (!response.isEmpty()) {
- transport->sendMessage(response, clientId);
+ transport->sendTextMessage(QString::fromUtf8(response));
}
}
diff --git a/src/webchannel/qmetaobjectpublisher_p.h b/src/webchannel/qmetaobjectpublisher_p.h
index 49b3ed0..dda18ae 100644
--- a/src/webchannel/qmetaobjectpublisher_p.h
+++ b/src/webchannel/qmetaobjectpublisher_p.h
@@ -51,16 +51,14 @@
#include <QPointer>
#include "qwebchannelglobal.h"
-#include "qwebchanneltransportinterface.h"
QT_BEGIN_NAMESPACE
class QWebChannel;
-
-class Q_WEBCHANNEL_EXPORT QMetaObjectPublisher : public QObject, public QWebChannelMessageHandlerInterface
+class Q_WEBCHANNEL_EXPORT QMetaObjectPublisher : public QObject
{
Q_OBJECT
- Q_INTERFACES(QWebChannelMessageHandlerInterface)
+
public:
explicit QMetaObjectPublisher(QWebChannel *webChannel);
virtual ~QMetaObjectPublisher();
@@ -161,13 +159,14 @@ public:
*/
void setBlockUpdates(bool block);
+Q_SIGNALS:
+ void blockUpdatesChanged(bool block);
+
+public Q_SLOTS:
/**
* Parse the message as JSON and if it succeeds, call handleRequest with the obtained JSON object.
*/
- void handleMessage(const QString &message, QWebChannelTransportInterface* transport, int clientId) Q_DECL_OVERRIDE;
-
-Q_SIGNALS:
- void blockUpdatesChanged(bool block);
+ void handleMessage(const QString &message);
protected:
void timerEvent(QTimerEvent *) Q_DECL_OVERRIDE;
diff --git a/src/webchannel/qwebchannel.cpp b/src/webchannel/qwebchannel.cpp
index 75d1a4b..e4cf0d6 100644
--- a/src/webchannel/qwebchannel.cpp
+++ b/src/webchannel/qwebchannel.cpp
@@ -43,7 +43,7 @@
#include "qwebchannel.h"
#include "qwebchannel_p.h"
#include "qmetaobjectpublisher_p.h"
-#include "qwebchanneltransportinterface.h"
+#include "qwebchannelabstracttransport.h"
#include <QJsonDocument>
#include <QJsonObject>
@@ -64,6 +64,14 @@ QByteArray generateJSONMessage(const QJsonValue &id, const QJsonValue &data, boo
return doc.toJson(QJsonDocument::Compact);
}
+void QWebChannelPrivate::_q_transportDestroyed(QObject *object)
+{
+ const int idx = transports.indexOf(static_cast<QWebChannelAbstractTransport*>(object));
+ if (idx != -1) {
+ transports.remove(idx);
+ }
+}
+
QWebChannel::QWebChannel(QObject *parent)
: QObject(parent)
, d(new QWebChannelPrivate)
@@ -75,9 +83,6 @@ QWebChannel::QWebChannel(QObject *parent)
QWebChannel::~QWebChannel()
{
- foreach (QWebChannelTransportInterface *transport, d->transports) {
- transport->setMessageHandler(Q_NULLPTR);
- }
}
void QWebChannel::registerObjects(const QHash< QString, QObject * > &objects)
@@ -109,20 +114,24 @@ void QWebChannel::setBlockUpdates(bool block)
d->publisher->setBlockUpdates(block);
}
-void QWebChannel::connectTo(QWebChannelTransportInterface *transport)
+void QWebChannel::connectTo(QWebChannelAbstractTransport *transport)
{
Q_ASSERT(transport);
if (!d->transports.contains(transport)) {
d->transports << transport;
- transport->setMessageHandler(d->publisher);
+ connect(transport, &QWebChannelAbstractTransport::textMessageReceived,
+ d->publisher, &QMetaObjectPublisher::handleMessage,
+ Qt::UniqueConnection);
+ connect(transport, SIGNAL(destroyed(QObject*)),
+ this, SLOT(_q_transportDestroyed(QObject*)));
}
}
-void QWebChannel::disconnectFrom(QWebChannelTransportInterface *transport)
+void QWebChannel::disconnectFrom(QWebChannelAbstractTransport *transport)
{
const int idx = d->transports.indexOf(transport);
if (idx != -1) {
- transport->setMessageHandler(Q_NULLPTR);
+ disconnect(transport, 0, this, 0);
d->transports.remove(idx);
}
}
@@ -135,9 +144,12 @@ void QWebChannel::sendMessage(const QJsonValue &id, const QJsonValue &data) cons
}
const QByteArray &message = generateJSONMessage(id, data, false);
- foreach (QWebChannelTransportInterface *transport, d->transports) {
- transport->sendMessage(message);
+ const QString &messageText = QString::fromUtf8(message);
+ foreach (QWebChannelAbstractTransport *transport, d->transports) {
+ transport->sendTextMessage(messageText);
}
}
QT_END_NAMESPACE
+
+#include "moc_qwebchannel.cpp"
diff --git a/src/webchannel/qwebchannel.h b/src/webchannel/qwebchannel.h
index 76e77b8..5016b52 100644
--- a/src/webchannel/qwebchannel.h
+++ b/src/webchannel/qwebchannel.h
@@ -51,7 +51,7 @@
QT_BEGIN_NAMESPACE
struct QWebChannelPrivate;
-class QWebChannelTransportInterface;
+class QWebChannelAbstractTransport;
class Q_WEBCHANNEL_EXPORT QWebChannel : public QObject
{
@@ -89,8 +89,8 @@ public:
*/
void setBlockUpdates(bool block);
- void connectTo(QWebChannelTransportInterface *transport);
- void disconnectFrom(QWebChannelTransportInterface *transport);
+ void connectTo(QWebChannelAbstractTransport *transport);
+ void disconnectFrom(QWebChannelAbstractTransport *transport);
Q_SIGNALS:
void blockUpdatesChanged(bool block);
@@ -100,6 +100,8 @@ public Q_SLOTS:
private:
QScopedPointer<QWebChannelPrivate> d;
+ Q_PRIVATE_SLOT(d, void _q_transportDestroyed(QObject*));
+ friend class QMetaObjectPublisher;
friend class QmlWebChannel;
friend class TestWebChannel;
};
diff --git a/src/webchannel/qwebchannel.js b/src/webchannel/qwebchannel.js
index 278f423..291c10b 100644
--- a/src/webchannel/qwebchannel.js
+++ b/src/webchannel/qwebchannel.js
@@ -102,10 +102,8 @@ var QWebChannel = function(baseUrlOrSocket, initCallback, rawChannel)
this.socket.onmessage = this.messageReceived
setTimeout(this.initialized, 0);
} else {
- ///TODO: use ssl?
- var socketUrl = "ws://" + baseUrlOrSocket;
///TODO: use QWebChannel protocol, once custom protcols are supported by QtWebSocket
- this.socket = new WebSocket(socketUrl /*, "QWebChannel" */);
+ this.socket = new WebSocket(baseUrlOrSocket/*, "QWebChannel" */);
this.socket.onopen = this.initialized
this.socket.onclose = function()
@@ -147,7 +145,7 @@ var QWebChannel = function(baseUrlOrSocket, initCallback, rawChannel)
channel.send({"id": id, "data": data});
};
- this.objectMap = {};
+ this.objects = {};
this.initMetaObjectPublisher = function(doneCallback)
{
@@ -157,7 +155,7 @@ var QWebChannel = function(baseUrlOrSocket, initCallback, rawChannel)
channel.subscribe(
QWebChannelMessageTypes.signal,
function(payload) {
- var object = window[payload.object] || channel.objectMap[payload.object];
+ var object = channel.objects[payload.object];
if (object) {
object.signalEmitted(payload.signal, payload.args);
} else {
@@ -171,7 +169,7 @@ var QWebChannel = function(baseUrlOrSocket, initCallback, rawChannel)
function(payload) {
for (var i in payload) {
var data = payload[i];
- var object = window[data.object] || channel.objectMap[data.object];
+ var object = channel.objects[data.object];
if (object) {
object.propertyUpdate(data.signals, data.properties);
} else {
@@ -192,7 +190,6 @@ var QWebChannel = function(baseUrlOrSocket, initCallback, rawChannel)
for (var objectName in payload) {
var data = payload[objectName];
var object = new QObject(objectName, data, channel);
- window[objectName] = object;
}
if (doneCallback) {
doneCallback(channel);
@@ -213,7 +210,7 @@ var QWebChannel = function(baseUrlOrSocket, initCallback, rawChannel)
function QObject(name, data, webChannel)
{
this.__id__ = name;
- webChannel.objectMap[name] = this;
+ webChannel.objects[name] = this;
// List of callbacks that get invoked upon signal emission
this.__objectSignals__ = {};
@@ -233,18 +230,23 @@ function QObject(name, data, webChannel)
return response;
}
var objectId = response.id;
- if (webChannel.objectMap[objectId])
- return webChannel.objectMap[objectId];
+ if (webChannel.objects[objectId])
+ return webChannel.objects[objectId];
var qObject = new QObject( objectId, response.data, webChannel );
qObject.destroyed.connect(function() {
- if (webChannel.objectMap[objectId] === qObject) {
- delete webChannel.objectMap[objectId];
+ if (webChannel.objects[objectId] === qObject) {
+ delete webChannel.objects[objectId];
// reset the now deleted QObject to an empty {} object
// just assigning {} though would not have the desired effect, but the
// below also ensures all external references will see the empty map
- for (var prop in qObject) {
- delete qObject[prop];
+ // NOTE: this detour is necessary to workaround QTBUG-40021
+ var propertyNames = [];
+ for (var propertyName in qObject) {
+ propertyNames.push(propertyName);
+ }
+ for (var idx in propertyNames) {
+ delete qObject[propertyNames[idx]];
}
}
});
diff --git a/src/webchannel/qwebchannel_p.h b/src/webchannel/qwebchannel_p.h
index b81640e..fbdf2ef 100644
--- a/src/webchannel/qwebchannel_p.h
+++ b/src/webchannel/qwebchannel_p.h
@@ -43,22 +43,23 @@
#define QWEBCHANNEL_P_H
#include "qwebchannelglobal.h"
-#include "qwebchanneltransportinterface.h"
#include <QVector>
QT_BEGIN_NAMESPACE
class QJsonValue;
-class QWebChannelTransportInterface;
+class QWebChannelAbstractTransport;
class QMetaObjectPublisher;
Q_WEBCHANNEL_EXPORT QByteArray generateJSONMessage(const QJsonValue &id, const QJsonValue &data, bool response);
struct Q_WEBCHANNEL_EXPORT QWebChannelPrivate
{
- QVector<QWebChannelTransportInterface*> transports;
+ QVector<QWebChannelAbstractTransport*> transports;
QMetaObjectPublisher *publisher;
+
+ void _q_transportDestroyed(QObject* object);
};
QT_END_NAMESPACE
diff --git a/src/webchannel/qwebchannelabstracttransport.cpp b/src/webchannel/qwebchannelabstracttransport.cpp
new file mode 100644
index 0000000..86c3121
--- /dev/null
+++ b/src/webchannel/qwebchannelabstracttransport.cpp
@@ -0,0 +1,58 @@
+/****************************************************************************
+**
+** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff <milian.wolff@kdab.com>
+** Contact: http://www.qt-project.org/legal
+**
+** This file is part of the QtWebChannel module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Digia. For licensing terms and
+** conditions see http://qt.digia.com/licensing. For further information
+** use the contact form at http://qt.digia.com/contact-us.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Digia gives you certain additional
+** rights. These rights are described in the Digia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3.0 as published by the Free Software
+** Foundation and appearing in the file LICENSE.GPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU General Public License version 3.0 requirements will be
+** met: http://www.gnu.org/copyleft/gpl.html.
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include "qwebchannelabstracttransport.h"
+
+QT_BEGIN_NAMESPACE
+
+QWebChannelAbstractTransport::QWebChannelAbstractTransport(QObject *parent)
+: QObject(parent)
+{
+
+}
+
+QWebChannelAbstractTransport::~QWebChannelAbstractTransport()
+{
+
+}
+
+
+QT_END_NAMESPACE
diff --git a/src/webchannel/qwebsockettransport_p.h b/src/webchannel/qwebchannelabstracttransport.h
index b9bd9b0..c90f4b1 100644
--- a/src/webchannel/qwebsockettransport_p.h
+++ b/src/webchannel/qwebchannelabstracttransport.h
@@ -39,51 +39,34 @@
**
****************************************************************************/
-#ifndef QWEBCHANNELSOCKET_P_H
-#define QWEBCHANNELSOCKET_P_H
+#ifndef QWEBCHANNELABSTRACTTRANSPORT_H
+#define QWEBCHANNELABSTRACTTRANSPORT_H
-#include <QtWebSockets/QWebSocketServer>
-
-#include "qwebchanneltransportinterface.h"
+#include <QObject>
+#include <qwebchannelglobal.h>
QT_BEGIN_NAMESPACE
-class QWebSocketTransport;
-class QWebSocketTransportPrivate : public QWebSocketServer
+class Q_WEBCHANNEL_EXPORT QWebChannelAbstractTransport : public QObject
{
Q_OBJECT
public:
- QString m_secret;
- QString m_baseUrl;
- QWebChannelMessageHandlerInterface *m_messageHandler;
- QWebSocketTransport *m_transport;
-
- bool m_useSecret;
- bool m_starting;
-
- explicit QWebSocketTransportPrivate(QWebSocketTransport* transport, QObject *parent = 0);
- virtual ~QWebSocketTransportPrivate();
+ explicit QWebChannelAbstractTransport(QObject *parent = 0);
+ virtual ~QWebChannelAbstractTransport();
- void initLater();
- void sendMessage(const QString &message, int clientId);
+public Q_SLOTS:
+ /**
+ * Send a text @p message to the remote client.
+ */
+ virtual void sendTextMessage(const QString &message) = 0;
Q_SIGNALS:
- void failed(const QString &reason);
- void initialized();
- void baseUrlChanged(const QString &baseUrl);
- void textDataReceived(const QString &message);
-
-private Q_SLOTS:
- void validateNewConnection();
- void init();
- void socketError();
- void messageReceived(const QString &message);
- void clientDisconnected();
-
-private:
- QVector<QWebSocket*> m_clients;
+ /**
+ * Emitted when a new text message was received from the remote client.
+ */
+ void textMessageReceived(const QString &message);
};
QT_END_NAMESPACE
-#endif // QWEBCHANNELSOCKET_P_H
+#endif // QWEBCHANNELABSTRACTTRANSPORT_H
diff --git a/src/webchannel/qwebchanneltransportinterface.h b/src/webchannel/qwebchannelwebsockettransport.cpp
index c532732..59c9538 100644
--- a/src/webchannel/qwebchanneltransportinterface.h
+++ b/src/webchannel/qwebchannelwebsockettransport.cpp
@@ -39,56 +39,41 @@
**
****************************************************************************/
-#ifndef QWEBCHANNELTRANSPORTINTERFACE_H
-#define QWEBCHANNELTRANSPORTINTERFACE_H
+#include "qwebchannelwebsockettransport.h"
-#include <QObject>
+/*!
+ \inmodule QtWebChannel
+ \brief QWebChannelAbstractSocket implementation that uses a QWebSocket internally.
-#include <QtWebChannel/qwebchannelglobal.h>
+ The transport delegates all messages received over the QWebSocket over its
+ textMessageReceived signal. Analogously, all calls to sendTextMessage will
+ be send over the QWebSocket to the remote client.
+*/
QT_BEGIN_NAMESPACE
-class QWebChannelTransportInterface;
-class Q_WEBCHANNEL_EXPORT QWebChannelMessageHandlerInterface
+struct QWebChannelWebSocketTransportPrivate
{
-public:
- virtual ~QWebChannelMessageHandlerInterface() {}
-
- /**
- * Handle a text message from a web channel client.
- */
- virtual void handleMessage(const QString &message, QWebChannelTransportInterface* transport, int clientId) = 0;
+ QWebSocket *socket;
};
-#define QWebChannelMessageHandlerInterface_iid "org.qt-project.Qt.QWebChannelMessageHandlerInterface"
-Q_DECLARE_INTERFACE(QWebChannelMessageHandlerInterface, QWebChannelMessageHandlerInterface_iid);
-Q_DECLARE_METATYPE(QWebChannelMessageHandlerInterface*)
-
-class Q_WEBCHANNEL_EXPORT QWebChannelTransportInterface
+QWebChannelWebSocketTransport::QWebChannelWebSocketTransport(QWebSocket *socket)
+: QWebChannelAbstractTransport(socket)
+, d(new QWebChannelWebSocketTransportPrivate)
{
-public:
- virtual ~QWebChannelTransportInterface() {}
+ d->socket = socket;
+ connect(socket, &QWebSocket::textMessageReceived,
+ this, &QWebChannelWebSocketTransport::textMessageReceived);
+}
- /**
- * Send a text message to all web channel clients.
- */
- virtual void sendMessage(const QString &message, int clientId = -1) const = 0;
+QWebChannelWebSocketTransport::~QWebChannelWebSocketTransport()
+{
- /**
- * Send a binary message to all web channel clients.
- */
- virtual void sendMessage(const QByteArray &message, int clientId = -1) const = 0;
+}
- /**
- * Sets the message handler that will be called on incoming messages from web channel clients.
- */
- virtual void setMessageHandler(QWebChannelMessageHandlerInterface *handler) = 0;
-};
-
-#define QWebChannelTransportInterface_iid "org.qt-project.Qt.QWebChannelTransportInterface"
-Q_DECLARE_INTERFACE(QWebChannelTransportInterface, QWebChannelTransportInterface_iid);
-Q_DECLARE_METATYPE(QWebChannelTransportInterface*)
+void QWebChannelWebSocketTransport::sendTextMessage(const QString &message)
+{
+ d->socket->sendTextMessage(message);
+}
QT_END_NAMESPACE
-
-#endif // QWEBCHANNELTRANSPORTINTERFACE_H
diff --git a/src/webchannel/qwebsockettransport.h b/src/webchannel/qwebchannelwebsockettransport.h
index b3e484f..b718b9b 100644
--- a/src/webchannel/qwebsockettransport.h
+++ b/src/webchannel/qwebchannelwebsockettransport.h
@@ -39,43 +39,30 @@
**
****************************************************************************/
-#ifndef QWEBSOCKETTRANSPORT_H
-#define QWEBSOCKETTRANSPORT_H
+#ifndef QWEBCHANNELWEBSOCKETTRANSPORT_H
+#define QWEBCHANNELWEBSOCKETTRANSPORT_H
-#include "qwebchanneltransportinterface.h"
+#include <QObject>
+#include <QtWebChannel/QWebChannelAbstractTransport>
+#include <QtWebChannel/qwebchannelglobal.h>
+#include <QtWebSockets/QWebSocket>
QT_BEGIN_NAMESPACE
-class QWebSocketTransportPrivate;
-class Q_WEBCHANNEL_EXPORT QWebSocketTransport : public QObject, public QWebChannelTransportInterface
+struct QWebChannelWebSocketTransportPrivate;
+class Q_WEBCHANNEL_EXPORT QWebChannelWebSocketTransport : public QWebChannelAbstractTransport
{
Q_OBJECT
- Q_INTERFACES(QWebChannelTransportInterface)
- Q_PROPERTY(QString baseUrl READ baseUrl NOTIFY baseUrlChanged)
- Q_PROPERTY(bool useSecret READ useSecret WRITE setUseSecret)
public:
- explicit QWebSocketTransport(QObject *parent = 0);
- ~QWebSocketTransport() Q_DECL_OVERRIDE;
+ explicit QWebChannelWebSocketTransport(QWebSocket *socket);
+ virtual ~QWebChannelWebSocketTransport();
- void sendMessage(const QByteArray &message, int clientId = -1) const Q_DECL_OVERRIDE;
- void sendMessage(const QString &message, int clientId = -1) const Q_DECL_OVERRIDE;
- void setMessageHandler(QWebChannelMessageHandlerInterface *handler) Q_DECL_OVERRIDE;
-
- QString baseUrl() const;
-
- void setUseSecret(bool);
- bool useSecret() const;
-
-Q_SIGNALS:
- void baseUrlChanged(const QString &baseUrl);
- void failed(const QString &reason);
- void initialized();
- void messageReceived(const QString &message);
+ void sendTextMessage(const QString &message) Q_DECL_OVERRIDE;
private:
- QScopedPointer<QWebSocketTransportPrivate> d;
+ QScopedPointer<QWebChannelWebSocketTransportPrivate> d;
};
QT_END_NAMESPACE
-#endif // QWEBSOCKETTRANSPORT_H
+#endif // QWEBCHANNELWEBSOCKETTRANSPORT_H
diff --git a/src/webchannel/qwebsockettransport.cpp b/src/webchannel/qwebsockettransport.cpp
deleted file mode 100644
index 8c25a9b..0000000
--- a/src/webchannel/qwebsockettransport.cpp
+++ /dev/null
@@ -1,212 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff <milian.wolff@kdab.com>
-** Contact: http://www.qt-project.org/legal
-**
-** This file is part of the QtWebChannel module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and Digia. For licensing terms and
-** conditions see http://qt.digia.com/licensing. For further information
-** use the contact form at http://qt.digia.com/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 2.1 requirements
-** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** In addition, as a special exception, Digia gives you certain additional
-** rights. These rights are described in the Digia Qt LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 3.0 as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 3.0 requirements will be
-** met: http://www.gnu.org/copyleft/gpl.html.
-**
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "qwebsockettransport.h"
-#include "qwebsockettransport_p.h"
-
-#include <QUuid>
-
-#include <QtWebSockets/QWebSocket>
-
-QT_USE_NAMESPACE
-
-//BEGIN QWebSocketTransportPrivate
-
-QWebSocketTransportPrivate::QWebSocketTransportPrivate(QWebSocketTransport *transport, QObject *parent)
- : QWebSocketServer(QStringLiteral("QWebChannel Server"), NonSecureMode, parent)
- , m_messageHandler(Q_NULLPTR)
- , m_transport(transport)
- , m_useSecret(true)
- , m_starting(false)
-{
- connect(this, SIGNAL(acceptError(QAbstractSocket::SocketError)),
- SLOT(socketError()));
- connect(this, SIGNAL(newConnection()),
- SLOT(validateNewConnection()));
-}
-
-QWebSocketTransportPrivate::~QWebSocketTransportPrivate()
-{
- close();
- qDeleteAll(m_clients);
-}
-
-void QWebSocketTransportPrivate::initLater()
-{
- if (m_starting)
- return;
- metaObject()->invokeMethod(this, "init", Qt::QueuedConnection);
- m_starting = true;
-}
-
-void QWebSocketTransportPrivate::sendMessage(const QString &message, int clientId)
-{
- if (clientId == -1) {
- foreach (QWebSocket *client, m_clients) {
- client->sendTextMessage(message);
- }
- } else {
- m_clients.at(clientId)->sendTextMessage(message);
- }
-}
-
-void QWebSocketTransportPrivate::validateNewConnection()
-{
- QWebSocket *client = nextPendingConnection();
- // FIXME: client->protocol() != QStringLiteral("QWebChannel")
- // protocols are not supported in QtWebSockets yet...
- if (m_useSecret && client->requestUrl().path() != m_secret)
- {
- client->close(QWebSocketProtocol::CloseCodeBadOperation);
- client->deleteLater();
- } else {
- connect(client, SIGNAL(textMessageReceived(QString)),
- SLOT(messageReceived(QString)));
- connect(client, SIGNAL(disconnected()),
- SLOT(clientDisconnected()));
- m_clients << client;
- }
-}
-
-void QWebSocketTransportPrivate::init()
-{
- close();
-
- m_starting = false;
- if (m_useSecret) {
- m_secret = QUuid::createUuid().toString();
- // replace { by /
- m_secret[0] = QLatin1Char('/');
- // chop of trailing }
- m_secret.chop(1);
- }
-
- if (!listen(QHostAddress::LocalHost)) {
- emit failed(errorString());
- return;
- }
-
- m_baseUrl = QStringLiteral("127.0.0.1:%1%2").arg(serverPort()).arg(m_secret);
- emit initialized();
- emit baseUrlChanged(m_baseUrl);
-}
-
-void QWebSocketTransportPrivate::socketError()
-{
- emit failed(errorString());
-}
-
-void QWebSocketTransportPrivate::messageReceived(const QString &message)
-{
- if (m_messageHandler) {
- QWebSocket *client = qobject_cast<QWebSocket*>(sender());
- m_messageHandler->handleMessage(message, m_transport, m_clients.indexOf(client));
- }
- emit textDataReceived(message);
-}
-
-void QWebSocketTransportPrivate::clientDisconnected()
-{
- QWebSocket *client = qobject_cast<QWebSocket*>(sender());
- if (!client) {
- return;
- }
- const int idx = m_clients.indexOf(client);
- Q_ASSERT(idx != -1);
- m_clients.remove(idx);
- client->deleteLater();
-}
-
-//END QWebSocketTransportPrivate
-
-QWebSocketTransport::QWebSocketTransport(QObject *parent)
- : QObject(parent)
- , d(new QWebSocketTransportPrivate(this))
-{
- connect(d.data(), SIGNAL(textDataReceived(QString)),
- SIGNAL(messageReceived(QString)));
- connect(d.data(), SIGNAL(failed(QString)),
- SIGNAL(failed(QString)));
- connect(d.data(), SIGNAL(initialized()),
- SIGNAL(initialized()));
- connect(d.data(), SIGNAL(baseUrlChanged(QString)),
- SIGNAL(baseUrlChanged(QString)));
-
- d->initLater();
-}
-
-QWebSocketTransport::~QWebSocketTransport()
-{
-
-}
-
-void QWebSocketTransport::sendMessage(const QByteArray &message, int clientId) const
-{
- d->sendMessage(QString::fromUtf8(message), clientId);
-}
-
-void QWebSocketTransport::sendMessage(const QString &message, int clientId) const
-{
- d->sendMessage(message, clientId);
-}
-
-void QWebSocketTransport::setMessageHandler(QWebChannelMessageHandlerInterface *handler)
-{
- d->m_messageHandler = handler;
-}
-
-QString QWebSocketTransport::baseUrl() const
-{
- return d->m_baseUrl;
-}
-
-void QWebSocketTransport::setUseSecret(bool s)
-{
- if (d->m_useSecret == s)
- return;
- d->m_useSecret = s;
- d->initLater();
-}
-
-bool QWebSocketTransport::useSecret() const
-{
- return d->m_useSecret;
-}
diff --git a/src/webchannel/webchannel.pro b/src/webchannel/webchannel.pro
index c6e6d69..a50beaa 100644
--- a/src/webchannel/webchannel.pro
+++ b/src/webchannel/webchannel.pro
@@ -12,20 +12,20 @@ OTHER_FILES = \
PUBLIC_HEADERS += \
qwebchannel.h \
- qwebchanneltransport.h \
- qwebsockettransport.h
+ qwebchannelabstracttransport.h \
+ qwebchannelwebsockettransport.h
PRIVATE_HEADERS += \
qwebchannel_p.h \
qmetaobjectpublisher_p.h \
- qwebsockettransport_p.h \
variantargument_p.h \
signalhandler_p.h
SOURCES += \
qwebchannel.cpp \
qmetaobjectpublisher.cpp \
- qwebsockettransport.cpp
+ qwebchannelabstracttransport.cpp \
+ qwebchannelwebsockettransport.cpp
qtHaveModule(qml) {
QT += qml