summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMilian Wolff <milian.wolff@kdab.com>2014-07-30 12:20:08 +0200
committerLutz Schönemann <lutz.schoenemann@basyskom.com>2014-12-08 16:02:45 +0100
commit0a43a43a166d2e2b551f543de61090637bd8b387 (patch)
treeb27ead870eef7af20f3d35a717d57bd0d262a911
parente50edc952ce15f3c11f4cdfad74ec984043cb080 (diff)
downloadqtwebchannel-0a43a43a166d2e2b551f543de61090637bd8b387.tar.gz
Do not broadcast initialization data to all clients.
Instead, send the data as a response to the initialization request message. This simplifies the code and makes it more predictable, as we do not spam all clients with initialization broadcasts anymore. Note that the pending initialization "feature" is removed, but I don't see a need for it anymore. If you want to delay client initialization, do it on the client side. Change-Id: I1ab71fd6c9e809ccb6085f1a3fbac3eb9b2e910b Reviewed-by: Jocelyn Turcotte <jocelyn.turcotte@digia.com>
-rw-r--r--src/webchannel/qmetaobjectpublisher.cpp45
-rw-r--r--src/webchannel/qmetaobjectpublisher_p.h6
-rw-r--r--src/webchannel/qwebchannel.js29
-rw-r--r--tests/auto/webchannel/tst_webchannel.cpp4
4 files changed, 31 insertions, 53 deletions
diff --git a/src/webchannel/qmetaobjectpublisher.cpp b/src/webchannel/qmetaobjectpublisher.cpp
index eeab014..527b3df 100644
--- a/src/webchannel/qmetaobjectpublisher.cpp
+++ b/src/webchannel/qmetaobjectpublisher.cpp
@@ -73,6 +73,15 @@ const QString KEY_ARGS = QStringLiteral("args");
const QString KEY_PROPERTY = QStringLiteral("property");
const QString KEY_VALUE = QStringLiteral("value");
+QJsonObject createResponse(const QJsonValue &id, const QJsonValue &data)
+{
+ QJsonObject response;
+ response[KEY_TYPE] = TypeResponse;
+ response[KEY_ID] = id;
+ response[KEY_DATA] = data;
+ return response;
+}
+
/// TODO: what is the proper value here?
const int PROPERTY_UPDATE_INTERVAL = 50;
}
@@ -83,7 +92,6 @@ QMetaObjectPublisher::QMetaObjectPublisher(QWebChannel *webChannel)
, signalHandler(this)
, clientIsIdle(false)
, blockUpdates(false)
- , pendingInit(false)
, propertyUpdatesInitialized(false)
{
}
@@ -208,12 +216,8 @@ void QMetaObjectPublisher::setClientIsIdle(bool isIdle)
}
}
-void QMetaObjectPublisher::initializeClients()
+QJsonObject QMetaObjectPublisher::initializeClient()
{
- if (!webChannel) {
- return;
- }
-
QJsonObject objectInfos;
{
const QHash<QString, QObject *>::const_iterator end = registeredObjects.constEnd();
@@ -225,12 +229,8 @@ void QMetaObjectPublisher::initializeClients()
objectInfos[it.key()] = info;
}
}
- QJsonObject message;
- message[KEY_TYPE] = TypeInit;
- message[KEY_DATA] = objectInfos;
- broadcastMessage(message);
propertyUpdatesInitialized = true;
- pendingInit = false;
+ return objectInfos;
}
void QMetaObjectPublisher::initializePropertyUpdates(const QObject *const object, const QJsonObject &objectInfo)
@@ -474,11 +474,12 @@ void QMetaObjectPublisher::handleMessage(const QJsonObject &message, QWebChannel
if (type == TypeIdle) {
setClientIsIdle(true);
} else if (type == TypeInit) {
- if (!blockUpdates) {
- initializeClients();
- } else {
- pendingInit = true;
+ if (!message.contains(KEY_ID)) {
+ qWarning("JSON message object is missing the id property: %s",
+ QJsonDocument(message).toJson().constData());
+ return;
}
+ transport->sendMessage(createResponse(message.value(KEY_ID), initializeClient()));
} else if (type == TypeDebug) {
static QTextStream out(stdout);
out << "DEBUG: " << message.value(KEY_DATA).toString() << endl;
@@ -496,11 +497,9 @@ void QMetaObjectPublisher::handleMessage(const QJsonObject &message, QWebChannel
QJsonDocument(message).toJson().constData());
return;
}
- QJsonObject response;
- response[KEY_TYPE] = TypeResponse;
- response[KEY_ID] = message.value(KEY_ID);
- response[KEY_DATA] = invokeMethod(object, message.value(KEY_METHOD).toInt(-1), message.value(KEY_ARGS).toArray());
- transport->sendMessage(response);
+ transport->sendMessage(createResponse(message.value(KEY_ID),
+ invokeMethod(object, message.value(KEY_METHOD).toInt(-1),
+ message.value(KEY_ARGS).toArray())));
} else if (type == TypeConnectToSignal) {
signalHandler.connectTo(object, message.value(KEY_SIGNAL).toInt(-1));
} else if (type == TypeDisconnectFromSignal) {
@@ -526,11 +525,7 @@ void QMetaObjectPublisher::setBlockUpdates(bool block)
blockUpdates = block;
if (!blockUpdates) {
- if (pendingInit) {
- initializeClients();
- } else {
- sendPendingPropertyUpdates();
- }
+ sendPendingPropertyUpdates();
} else if (timer.isActive()) {
timer.stop();
}
diff --git a/src/webchannel/qmetaobjectpublisher_p.h b/src/webchannel/qmetaobjectpublisher_p.h
index a7cdda7..eda17d9 100644
--- a/src/webchannel/qmetaobjectpublisher_p.h
+++ b/src/webchannel/qmetaobjectpublisher_p.h
@@ -108,7 +108,7 @@ public:
*
* Furthermore, if that was not done already, connect to their property notify signals.
*/
- void initializeClients();
+ QJsonObject initializeClient();
/**
* Go through all properties of the given object and connect to their notify signal.
@@ -195,10 +195,6 @@ private:
// true when no property updates should be sent, false otherwise
bool blockUpdates;
- // true when at least one client needs to be initialized,
- // i.e. when a Qt.init came in which was not handled yet.
- bool pendingInit;
-
// true when at least one client was initialized and thus
// the property updates have been initialized and the
// object info map set.
diff --git a/src/webchannel/qwebchannel.js b/src/webchannel/qwebchannel.js
index d2c6525..13e9da5 100644
--- a/src/webchannel/qwebchannel.js
+++ b/src/webchannel/qwebchannel.js
@@ -82,9 +82,6 @@ var QWebChannel = function(transport, initCallback)
case QWebChannelMessageTypes.propertyUpdate:
channel.handlePropertyUpdate(data);
break;
- case QWebChannelMessageTypes.init:
- channel.handleInit(data);
- break;
default:
console.error("invalid message received:", message.data);
break;
@@ -149,30 +146,20 @@ var QWebChannel = function(transport, initCallback)
channel.exec({type: QWebChannelMessageTypes.idle});
}
- // prevent multiple initialization which might happen with multiple webchannel clients.
- this.initialized = false;
- this.handleInit = function(message)
+ this.debug = function(message)
{
- if (channel.initialized) {
- return;
- }
- channel.initialized = true;
- for (var objectName in message.data) {
- var data = message.data[objectName];
- var object = new QObject(objectName, data, channel);
+ channel.send({type: QWebChannelMessageTypes.debug, data: message});
+ };
+
+ channel.exec({type: QWebChannelMessageTypes.init}, function(data) {
+ for (var objectName in data) {
+ var object = new QObject(objectName, data[objectName], channel);
}
if (initCallback) {
initCallback(channel);
}
channel.exec({type: QWebChannelMessageTypes.idle});
- }
-
- this.debug = function(message)
- {
- channel.send({type: QWebChannelMessageTypes.debug, data: message});
- };
-
- channel.exec({type: QWebChannelMessageTypes.init});
+ });
};
function QObject(name, data, webChannel)
diff --git a/tests/auto/webchannel/tst_webchannel.cpp b/tests/auto/webchannel/tst_webchannel.cpp
index 4827ea7..5060028 100644
--- a/tests/auto/webchannel/tst_webchannel.cpp
+++ b/tests/auto/webchannel/tst_webchannel.cpp
@@ -282,7 +282,7 @@ void TestWebChannel::benchInitializeClients()
QMetaObjectPublisher *publisher = channel.d_func()->publisher;
QBENCHMARK {
- publisher->initializeClients();
+ publisher->initializeClient();
publisher->propertyUpdatesInitialized = false;
publisher->signalToPropertyMap.clear();
@@ -304,7 +304,7 @@ void TestWebChannel::benchPropertyUpdates()
}
channel.registerObjects(objects);
- channel.d_func()->publisher->initializeClients();
+ channel.d_func()->publisher->initializeClient();
QBENCHMARK {
foreach (BenchObject *obj, objectList) {