summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/webchannel/doc/src/index.qdoc13
-rw-r--r--src/webchannel/qmetaobjectpublisher.cpp24
-rw-r--r--src/webchannel/qmetaobjectpublisher_p.h9
-rw-r--r--src/webchannel/qwebchannel.cpp5
4 files changed, 42 insertions, 9 deletions
diff --git a/src/webchannel/doc/src/index.qdoc b/src/webchannel/doc/src/index.qdoc
index 43f4e6f..5529093 100644
--- a/src/webchannel/doc/src/index.qdoc
+++ b/src/webchannel/doc/src/index.qdoc
@@ -31,13 +31,12 @@
\title Qt WebChannel
\brief Bridges the gap between Qt applications and HTML/JavaScript.
- Qt WebChannel enables peer-to-peer communication between the server
- (QML/C++ application) and the client (HTML/JavaScript or QML application). The
- transport mechanism is supported out of the box by \l{Qt WebEngine}. It works on all
- browsers that support \l{Qt WebSockets}, enabling Qt WebChannel applications
- to run in any JavaScript runtime. Additionally, a custom transport
- mechanism can also be implemented using Qt WebSockets to support Qt
- WebChannel-based communication.
+ Qt WebChannel enables peer-to-peer communication between a server (QML/C++
+ application) and a client (HTML/JavaScript or QML application). It is
+ supported out of the box by \l{Qt WebEngine}. In addition it can work on all
+ browsers that support \l{Qt WebSockets}{WebSockets}, enabling Qt WebChannel
+ clients to run in any JavaScript environment (including QML). This requires
+ the implementation of a custom transport based on Qt WebSockets.
The module provides a JavaScript library for seamless integration of C++
and QML applications with HTML/JavaScript and QML clients. The clients must use the
diff --git a/src/webchannel/qmetaobjectpublisher.cpp b/src/webchannel/qmetaobjectpublisher.cpp
index e9d93ea..66676f0 100644
--- a/src/webchannel/qmetaobjectpublisher.cpp
+++ b/src/webchannel/qmetaobjectpublisher.cpp
@@ -495,6 +495,29 @@ QVariant QMetaObjectPublisher::toVariant(const QJsonValue &value, int targetType
return variant;
}
+void QMetaObjectPublisher::transportRemoved(QWebChannelAbstractTransport *transport)
+{
+ auto it = transportedWrappedObjects.find(transport);
+ // It is not allowed to modify a container while iterating over it. So save
+ // objects which should be removed and call objectDestroyed() on them later.
+ QVector<QObject*> objectsForDeletion;
+ while (it != transportedWrappedObjects.end() && it.key() == transport) {
+ if (wrappedObjects.contains(it.value())) {
+ QVector<QWebChannelAbstractTransport*> &transports = wrappedObjects[it.value()].transports;
+ transports.removeOne(transport);
+ if (transports.isEmpty())
+ objectsForDeletion.append(wrappedObjects[it.value()].object);
+ }
+
+ it++;
+ }
+
+ transportedWrappedObjects.remove(transport);
+
+ foreach (QObject *obj, objectsForDeletion)
+ objectDestroyed(obj);
+}
+
// NOTE: transport can be a nullptr
// in such a case, we need to ensure that the property is registered to
// the target transports of the parentObjectId
@@ -526,6 +549,7 @@ QJsonValue QMetaObjectPublisher::wrapResult(const QVariant &result, QWebChannelA
oi.transports = webChannel->d_func()->transports;
}
wrappedObjects.insert(id, oi);
+ transportedWrappedObjects.insert(transport, id);
initializePropertyUpdates(object, classInfo);
} else if (wrappedObjects.contains(id)) {
diff --git a/src/webchannel/qmetaobjectpublisher_p.h b/src/webchannel/qmetaobjectpublisher_p.h
index 29956e0..830e510 100644
--- a/src/webchannel/qmetaobjectpublisher_p.h
+++ b/src/webchannel/qmetaobjectpublisher_p.h
@@ -94,7 +94,7 @@ public:
virtual ~QMetaObjectPublisher();
/**
- * Register @p object nuder the given @p id.
+ * Register @p object under the given @p id.
*
* The properties, signals and public methods of the QObject are
* published to the remote client, where an object with the given identifier
@@ -177,6 +177,11 @@ public:
QVariant toVariant(const QJsonValue &value, int targetType) const;
/**
+ * Remove wrapped objects which last transport relation is with the passed transport object.
+ */
+ void transportRemoved(QWebChannelAbstractTransport *transport);
+
+ /**
* Given a QVariant containing a QObject*, wrap the object and register for property updates
* return the objects class information.
*
@@ -257,6 +262,8 @@ private:
// Map of objects wrapped from invocation returns
QHash<QString, ObjectInfo> wrappedObjects;
+ // Map of transports to wrapped object ids
+ QMultiHash<QWebChannelAbstractTransport*, QString> transportedWrappedObjects;
// Map of objects to maps of signal indices to a set of all their property indices.
// The last value is a set as a signal can be the notify signal of multiple properties.
diff --git a/src/webchannel/qwebchannel.cpp b/src/webchannel/qwebchannel.cpp
index c2e0d19..0e9a4c5 100644
--- a/src/webchannel/qwebchannel.cpp
+++ b/src/webchannel/qwebchannel.cpp
@@ -81,9 +81,11 @@ QT_BEGIN_NAMESPACE
*/
void QWebChannelPrivate::_q_transportDestroyed(QObject *object)
{
- const int idx = transports.indexOf(static_cast<QWebChannelAbstractTransport*>(object));
+ QWebChannelAbstractTransport *transport = static_cast<QWebChannelAbstractTransport*>(object);
+ const int idx = transports.indexOf(transport);
if (idx != -1) {
transports.remove(idx);
+ publisher->transportRemoved(transport);
}
}
@@ -252,6 +254,7 @@ void QWebChannel::disconnectFrom(QWebChannelAbstractTransport *transport)
disconnect(transport, 0, this, 0);
disconnect(transport, 0, d->publisher, 0);
d->transports.remove(idx);
+ d->publisher->transportRemoved(transport);
}
}