summaryrefslogtreecommitdiff
path: root/src
Commit message (Collapse)AuthorAgeFilesLines
...
* Merge QWebChannelSocket and QWebSocketTransport.Milian Wolff2014-03-215-162/+116
| | | | | | | | | The former was just the private implementation of the latter. This way, the code structure is more understandable to newcomers and follows existing best-practices. Change-Id: I07cf64370553f4c2de349b5f01e90b31112fee58 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* Fix minor coding style issues.Milian Wolff2014-03-213-8/+8
| | | | | | | | Add space between type name and & or *. Change-Id: I64bfe20510cb43ee0a0b6e08bd433fc657e925a0 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com> Reviewed-by: Frederik Gladhorn <frederik.gladhorn@digia.com>
* Mark some constructor as explicitSergio Ahumada2014-03-193-3/+3
| | | | | | Change-Id: I92c5b00d5bbcc08a241ed0382c13b6bf2676ca6f Reviewed-by: Milian Wolff <milian.wolff@kdab.com> Reviewed-by: Frederik Gladhorn <frederik.gladhorn@digia.com>
* Port code to QtWebSockets.Milian Wolff2014-03-067-616/+65
| | | | | | | | | | | | | This removes the custom WebSocket server implementation and replaces it by a dependency on the QtWebSockets module. Sadly, the QtWebSocket module does not yet support custom protocols. Also, there is quite some boiler plate code required, something which I want to simplify upstream in the QtWebSockets module later. Change-Id: I8066418fb1857d23b8593c443bc9a98ded917a99 Reviewed-by: Kurt Pattyn <pattyn.kurt@gmail.com> Reviewed-by: Frederik Gladhorn <frederik.gladhorn@digia.com>
* Make the underlying transport mechanism of the webchannel pluggable.Milian Wolff2014-02-0619-109/+658
| | | | | | | | | | | | | | | | | | | | | This enables us to optionally use navigator.qt instead of a WebSocket, which is nicer setup-wise and is also slightly faster: navigator.qt: 284.0 msecs per iteration (total: 2,840, iterations: 10) WebSocket: 295.8 msecs per iteration (total: 2,959, iterations: 10) The baseline is ca. 203 msecs, which would mean a performance boost of ca. 12.7%. Furthermore, this sets the fundation to eventually add a WebEngine transport mechanism. The WebViewTransport should also be removed and instead the WebView itself should directly implement the WebChannelTransportInterface. Change-Id: I368bb27e38ffa2f17ffeb7f5ae695690f6f5ad21 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* Fix clang warning about struct which was forward-declared as class.Milian Wolff2014-01-311-1/+1
| | | | | Change-Id: I7dc78213bc57cbfd63b021e00823c4aad105aa05 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* Fix compilation when building with namespaced Qt.Milian Wolff2014-01-3116-1/+59
| | | | | | | | Wrap everything in the QtWebChannel module with the Qt namespace or use the Qt namespace where appropriate. Change-Id: I1ef2b2f5eb22ec5e04ca76c034ef8ebf4043b899 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* Fixup license headers of the files written by me.Milian Wolff2014-01-1618-52/+37
| | | | | | | | | | | | Some tests referenced Nokia in their license even though that was never the case. The tests where written completely by me after Qt Nokia times. What is missing are the examples which are still mostly original work by Noam back then in Nokia times. The rest was (re-)written by me completely since then anyways. Change-Id: Ib423fb3459bcc1f7464a02de4fd82ddfd614d282 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* Properly convert JSON data to target type of function parameter.Milian Wolff2014-01-102-44/+9
| | | | | | | | | | | | | | | | | | | This used to work but broke in one of the last few commits apparently. Now we add a proper unit test to ensure it stays working. The issue was that JSON only knows e.g. numeric types stored as double. When we then try to call a method taking an int with the VariantArgument that tries to convert the double to int, we failed and produced an invalid QVariant which then converts to 0. Now we use the appropriate API to convert the JSON data to the correct target type before calling the method. Furthermore, it became clear that we can greatly cleanup the VariantArgument thanks to that. It now is reduced to just a QVariant wrapper class with an implicit cast operator to QGenericArgument. Change-Id: Ieaf60f548ea9584e7d760f9cd935da455787f376 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* Add declarative object-registration API to QML WebChannel.Milian Wolff2014-01-107-5/+244
| | | | | | | | | | | | The new registeredObjects list property is now preferred over the old imparative registerObject/registerObjects API. Items that are added to the list need an attached WebChannel.id property which holds the identifier under which the object is published to remote clients. Change-Id: I96a8047b9a85e27f3fd48c900180c22ebd20eb35 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* Fix warning about include in public header.Milian Wolff2014-01-091-1/+1
| | | | | | | | | | | QMake reported the following warnings which is fixed by this patch: QtWebChannel: WARNING: .../qwebchannel/src/webchannel/qwebchannel.h includes qwebchannelglobal.h when it should include QtWebChannel/qwebchannelglobal.h Change-Id: Ib6a330e372a9de32d9578aa17ea0d74257a23676 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* Fix regression in handling of var-emitting signals from QML.Milian Wolff2014-01-092-1/+24
| | | | | | | | | | | | Qt 5.3 propagates var-arguments of signals as QJSValue instead of as a QVariant. This then fails to be serialized to QJson, failing our unit tests. Now, QJSValue types are manually casted to QJsonValues which makes the tests pass again. Change-Id: I730c595eee214ebe3d1f83009cd5605f66407f55 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* Cleanup public API, remove private slot.Milian Wolff2014-01-084-12/+5
| | | | | Change-Id: I73a83380c571ed5a400b16cb255562bb8079eaac Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* Simplify usage of QWebChannel on the server side.Milian Wolff2014-01-0814-439/+671
| | | | | | | | | | | This is achieved by hiding the MetaObjectPublisher completely as private API. The QWebChannel is the only publisher API and now handles both the socket as well as the publisher internally. This now allows us to create a proper QML api in the new QmlWebChannel. Change-Id: I3096364af8485353ca9bc19df4a81a8e4552c3d7 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* Simplify QWebChannel usage by merging webchannel.js and qobject.js.Milian Wolff2014-01-084-193/+153
| | | | | | | | | | | The code now resides in a single qwebchannel.js file and there is only a single callback-nesting required to setup a MetaObjectPublisher connection. The server-side will be simplified in the next step. Change-Id: Ib5fc77a03c2b281c61af91713411eed571ec6108 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* Optimize: Use property-indices instead of names for notifications.Milian Wolff2014-01-083-30/+29
| | | | | | | | | | | | | | | This reduces the traffic as the indices are usually much smaller than the property names. As such, the benchPropertyUpdates gets a speed boost of about 9% (or 10ms vs. 11ms). As we need to transmit the index during initialization that degrades its performance slightly by ca. 4% (13ms vs. 12.5ms). Considering that the initialization only takes place once whereas the property updates potentially often, this is a good tradeoff. Change-Id: If7df3e360f1528b7d7aa26c63ce851363ae9fd6a Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* Fix assertion at shutdown or on QObject destruction.Milian Wolff2014-01-082-30/+35
| | | | | | | | | | When handling the destroyed signal of a QObject, the QMetaObject of the sender() will point to the global static QObject meta object. Thus, we also cache its signal argument types. This way, we are able to properly handle the destroyed signal with minimum effort. Change-Id: Iba1a3fc94d55adad178302cc847fd4285815e689 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* Optimize client initialization by using QJson directly.Milian Wolff2013-12-273-38/+44
| | | | | | | | | | | Before, we constructed QVariant maps and lists and then converted them to JSON to send the data to the webchannel. By obsoleting the conversion step, benchInitializeClients shows a good performance boost of ca. 19% (11.81ms vs 14.58ms). Change-Id: Ief8e8127207a046f481488a478cd6a18fa0ebffe Reviewed-by: Zeno Albisser <zeno.albisser@digia.com>
* Optimize SignalHandler by obsoleting the call to senderSignalIndex.Milian Wolff2013-12-271-17/+16
| | | | | | | | | This method is quite slow, and can be compared to two calls of sender(). We now encode the signal index in the methodId and thus do not have to call it anymore. The performance gain is about 27% (9.2 vs. 12.7ms). Change-Id: Iaa75efa27a54a21e27e62994de25cafd8136159d Reviewed-by: Zeno Albisser <zeno.albisser@digia.com>
* Cleanup and optimize code a bit by calling senderSignalIndex less.Milian Wolff2013-12-271-6/+10
| | | | | | | | | | | | | | Profiling shows that sender() and senderSignalIndex(), which again calls sender() internally, are the hotspots in benchPropertyUpdates. To speed things up a bit, call senderSignalIndex only once whenever a signal is emitted. The performance gain is about 27% (16ms vs. 22ms). While at it, also re-use the global s_destroyedSignalIndex static and also call sender() only once even when assertions are enabled. Change-Id: I90cd1a2b453e5c40d0f41276968f4545b42076bc Reviewed-by: Zeno Albisser <zeno.albisser@digia.com>
* Port MetaObjectPublisher benchmarks to C++.Milian Wolff2013-12-274-164/+195
| | | | | | | | | | | This allows us to remove the public API for the tests and allows for more tests and benchmarks in the future. To achieve this, we re-use the new qmetaobjectpublisher_p.h, which then also must be exported. Change-Id: I3c33b2f5be6cc674cd3092667151dd8da2263cf5 Reviewed-by: Zeno Albisser <zeno.albisser@digia.com>
* Add standalone C++/Qt example which opens HTML client in a browser.Milian Wolff2013-12-202-0/+21
| | | | | | | | | | | | | This example shows how to use the (currently quite ugly) raw C++ API to setup a webchannel without using QML at all. The HTML client is then handled by the users default browser. The example itself shows a simple chat between the HTML client and the C++/Qt server, with a line edit for input and a text edit showing the chat history. Change-Id: I8baf14efb9d0c5f5880d99710cf6317fe9b887b9 Reviewed-by: Zeno Albisser <zeno.albisser@digia.com>
* Restructure sources and assimilate to Qt module structure.Milian Wolff2013-12-1224-373/+481
| | | | | | | | | | | | | | | | | | | | | This module can hopefully be done in time for 5.3. This commit changes the source structure and QMake files to adapt to typical Qt modules. With this in place, we can now use QT += webchannel in qmake files to link against the pure Qt/C++ QtWebChannel library. The QML plugin is separated from it and can be loaded optionally, if the quick module could be found. Also added is now a qmlplugindump for tooling integration. Note that the Qt.labs namespace is removed. The test file structure is also adapted to how its done in the QtDeclarative module. Note that this setup apparently does not support to run tests without running make install first. Change-Id: I1c15d72e7ab5f525d5a6f651f4e965ef86bc17bd Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* Port the MetaObjectPublisher to C++.Milian Wolff2013-12-1110-492/+1041
| | | | | | | | | | | | | | | | | | | | | | | | | | | This will allow us to create a stand-alone WebChannel C++ library, without any QML dependencies, that can be used to publisher QObjects to remote clients running in any browser engine supporting WebSockets. The patch is large, as working with introspection through the QMetaObject from C++ is more complicated compared to QML. On the other hand, the move to C++ allows a much more performant implementation of quite some parts of the publisher. One thing is that signal and method invocations can be handled via numeric indices, where before we needed to transmit the string identifier of the signal or method. Eventually this can now also be applied to properties, further decreasing the size of messages between server and clients. Note that this patch contains quite some TODOs and rough edges, such as the invokable bench_* helper functions in the public API of the MetaObjectPublisher. These are to be seen as temporary, and will be cleaned up in followup commits later. This is done to prevent a further blow-up of this already big patch. Change-Id: I57e788d8a19edd410651611382d912f9ad6660c9 Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
* Optimize and cleanup code by moving WebChannel.qml logic into C++.Milian Wolff2013-12-058-82/+47
| | | | | | | | | | | | | | | By handling more logic on the C++ side, such as serializing the JSON data to QByteArray, we can save up to 6% in the propertyUpdates benchmark. Furthermore, this allows for some more code cleanup and obsoletes the WebChannel.qml file. Also, it is a first step towards removing the QML dependency and making it optional alltogether. Change-Id: Id610b5f2652da4a7ad867aef576fabcc40d3d92c Reviewed-by: Pierre Rossi <pierre.rossi@gmail.com>
* Cleanup code a bit.Milian Wolff2013-12-053-7/+5
| | | | | | | | | | | | The map-initializations are not required anymore, as the properties are now properly initialized. Furthermore, Qt.Debug messages are only handled by the MetaObjectPublisher, thus the webChannel.debug message should only be available to HTML clients which use qobject.js. Change-Id: Iae11a73d33d5eec3a90a264bf0418a5781523a22 Reviewed-by: Pierre Rossi <pierre.rossi@gmail.com>
* Make it possible to disconnect from signals on the client side.Milian Wolff2013-12-052-10/+56
| | | | | | | | To do so, we need to remember the connected functor and pass that to disconnect, in both the client side as well as the QML server side. Change-Id: Ic61fc5d2a203212278c23471c216683e309e2c9f Reviewed-by: Pierre Rossi <pierre.rossi@gmail.com>
* compileThomas McGuire2013-11-271-0/+1
| | | | | | Change-Id: If26e033dcb031678815277890be4ad2ebad3fd4b Reviewed-by: Milian Wolff <milian.wolff@kdab.com> Reviewed-by: Thomas McGuire <thomas.mcguire@kdab.com>
* Test QObject wrapping, when factory-style methods are called.Milian Wolff2013-11-251-0/+6
| | | | | | | | | | | | | | An HTML client can trigger the creation of new objects, or a published object on the server side might return other objects. These are then wrapped on the fly and can be used like the other objects. Note though that the HTML client can call deleteLater on these objects. Also, it does not yet work to wrap objects on the fly in signal arguments or property values. Change-Id: I92aa8a3e52f42d5325dd0771bbf9e2ae213e88f9 Reviewed-by: Arvid Nilsson <anilsson@blackberry.com> Reviewed-by: Pierre Rossi <pierre.rossi@gmail.com>
* Use strict mode in JavaScript files.Milian Wolff2013-11-252-0/+4
| | | | | | | | | No other changes seem to be required. Change-Id: Ie15639f74f09cbd303828c96f75d29283ec4d562 Reviewed-by: Arvid Nilsson <anilsson@blackberry.com> Reviewed-by: Chris H-C <chutten@blackberry.com> Reviewed-by: Pierre Rossi <pierre.rossi@gmail.com>
* Optimize QtMetaObjectPublisher::classInfoForObject.Milian Wolff2013-11-251-4/+13
| | | | | | | | | | | | | | | | | | | | | | | | This includes two optimizations which have been forgotten to be upstreamed before: a) For the common case of property notify signals named "...Changed", the string name is now not send anymore to the client. Instead, these cases are special-cased and constructed on the fly. This drastically reduces the size of Qt.init responses and property update messages. b) Furthermore, do not list signals as methods, further reducing the size of Qt.init response messages. Together this shows a noticeable reduce of CPU instructions in the benchmarks as recorded with perf: benchmark_classInfo: down ~10% benchmark_initializeClients: down ~2% benchmark_propertyUpdates: down ~1% Change-Id: I01e59f5c1dceedb893f7a3e3e127acb493baaa7f Reviewed-by: Michael Bruning <michael.bruning@digia.com> Reviewed-by: Pierre Rossi <pierre.rossi@gmail.com>
* Cleanup QML code.Milian Wolff2013-11-221-11/+4
| | | | | | | | | Instead of initializing the property maps in Component.onCompleted, use "var foo: ({})" instead. This looks suprising, but the "var foo: {}" syntax won't work - it's an empty binding expression closur, not a map. Change-Id: I9edeeeeeabb3a871a46d8bb8a991a4155040497a Reviewed-by: Zeno Albisser <zeno.albisser@digia.com>
* Add a test for the property update grouping.Milian Wolff2013-11-221-1/+1
| | | | | | | | | | | For performance reasons, we group property updates and send a single batch update notification. This is now tested to work as intended. This also uncovered a bug in webchannel.js when multiple functions subscribe to the same id. Change-Id: Ic8648d664dd1fe54df7e25fade6a6088386af992 Reviewed-by: Zeno Albisser <zeno.albisser@digia.com>
* Add an initial test suite for the MetaObjectPublisherMilian Wolff2013-11-221-2/+2
| | | | | | | | | | | | | | This tests the functionality of publishing a plain QtObject from QML to the HTML client. It tests property binding, i.e. reading and writing of an objects property on the client side, as well as change notification tracking. Furthermore a server-side method is invoked from the client and signal submission from the server to the client is tested. Change-Id: I62e544cddf4483b57535a9bc1e05a36105ec6622 Reviewed-by: Zeno Albisser <zeno.albisser@digia.com>
* Cleanup sources, mostly by removing QtCreator generated bloat.Milian Wolff2013-11-147-163/+0
| | | | | | | | | | | | | | This removes a lot of obsolete files and simplifies the build system of the examples. Furthermore, the examples can now be run without running make install first. It reuses the same import path as the test does. Note that the examples are not installable anymore now though. If this is required, it can be added again. Change-Id: Ic7ff80f734b035a03fb1a11a2df492c97298ceff Reviewed-by: Zeno Albisser <zeno.albisser@digia.com>
* Add unit test harness for QWebChannel and two initial tests.Milian Wolff2013-11-142-12/+22
| | | | | | | | | | | | This uncovered a bug in webchannel.js, which stringified strings leading to duplicated quoting. This is also fixed now. Furthermore, some QMake changes are required to make it possible to run the tests without first installing QWebChannel. Change-Id: If7e8f73a748f86f2d5c7d39000e90612367038af Reviewed-by: Zeno Albisser <zeno.albisser@digia.com> Reviewed-by: Pierre Rossi <pierre.rossi@gmail.com>
* Add KDAB/Qt-Project license to files edited by the previous commits.Milian Wolff2013-11-016-0/+18
| | | | | Change-Id: Idf344f46aa09a13dfe4db00203b7644006fbf944 Reviewed-by: Pierre Rossi <pierre.rossi@gmail.com>
* Make it possible to wrap QObject's on the fly.Milian Wolff2013-11-015-8/+168
| | | | | | | | This is required for factory-like methods on the C++/QML side, which we want to access from the HTML side as well. Change-Id: I2852bbc9c8effb6d6f49b5be784241a6e2320823 Reviewed-by: Pierre Rossi <pierre.rossi@gmail.com>
* Greatly optimize WebChannel in various ways.Milian Wolff2013-11-016-109/+460
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This is a big code drop - sorry for that. The benefits are worth it though, I'm sure. The optimizations were required to make the WebChannel useable even on a low-end embedded device with medium amount of traffic. The changes in this patch can be grouped into different parts: a) Do more in C++: Esp. by leveraging e.g. the new classInfoForObjects in QtMetaObjectPublisher (on the C++ side) one can greatly reduce the time required for initialization of the webchannel. b) Property Caching: Instead of requiring a socket roundtrip whenever a property is read on the HTML side, we now cache the property values on the HTML side. Note that for this to work properly, one needs to add proper notify signals to the property declarations, as otherwise the cache will not get updated. c) Grouping: Instead of sending separate messages to the clients for every property update, these signals are grouped by a 50ms timer, and then send aggregated to the client. This reduces the socket traffic, as more boiler plate can be shared. d) Compression: Some data was previously send repeatedly, such as property name and notify signal. This is now compressed internally where possible (i.e. for the ${propName}Changed naming scheme). e) Message Flood Prevention: Previously, one could easily flood an HTML client by sending data to it. If it could not work off the incoming stream one would freeze the HTML client. Now, we wait for an idle signal of the client prior to sending new data to it. Paired with the message grouping and property cache mentioned above, we are able to only send the newest data once the HTML client becomes active again. I.e. we discard now-obsolete property updates etc. Change-Id: I8f3ae16ed6c1f6a89b644acdce7efbf0f07fc786 Reviewed-by: Pierre Rossi <pierre.rossi@gmail.com>
* Use QStringLiteral here.Milian Wolff2013-11-011-1/+1
| | | | | Change-Id: Idd32243173775ec49b4a51a55faa85e47e11a4f1 Reviewed-by: Pierre Rossi <pierre.rossi@gmail.com>
* Optimize: If no callback is given, send data directly without execId.Milian Wolff2013-11-011-0/+5
| | | | | Change-Id: I47345fc52677b68ae75d018484b495fc81949054 Reviewed-by: Pierre Rossi <pierre.rossi@gmail.com>
* Add debug method to webchannel.Milian Wolff2013-11-011-1/+6
| | | | | Change-Id: Id4400b63f0bd5180194523f1efbac8b82c4dbe91 Reviewed-by: Pierre Rossi <pierre.rossi@gmail.com>
* Optimize: Share more byte array literals.Milian Wolff2013-11-011-7/+9
| | | | | Change-Id: Id7b35aab5012e1eba84fb3685b3bc6619aa92580 Reviewed-by: Pierre Rossi <pierre.rossi@gmail.com>
* Optimize: create the web socket header only once.Milian Wolff2013-11-012-11/+13
| | | | | | | | For channels with multiple clients we used to create it once for every client which is not needed. Change-Id: Ib1be0c9f7bc78c0415fe2e9f6f8aa5112d0156c6 Reviewed-by: Pierre Rossi <pierre.rossi@gmail.com>
* Fix wrapping of execIdThomas McGuire2013-11-011-1/+1
| | | | | Change-Id: I18a596c18530b18a833a58e734ce484caa6ae68f Reviewed-by: Pierre Rossi <pierre.rossi@gmail.com>
* Make it possible to connect multiple WebChannels to the same server.Milian Wolff2013-11-011-3/+12
| | | | | | | | | | | In principle everything worked before already, with the difference that responses to channel.exec could not properly be distinguished. This is now fixed by adding a UUID to the WebChannel and sending that along with the integer exec ID and comparing it in response messages. Change-Id: I954716b04c1d9a41fffb8b9bb736a1fa45fec7f2 Reviewed-by: Pierre Rossi <pierre.rossi@gmail.com>
* Use 127.0.0.1. instead of localhost.Milian Wolff2013-11-011-1/+1
| | | | | Change-Id: I5948de7edff3aa8a58c9cc6e3789c4e7fffb7260 Reviewed-by: Pierre Rossi <pierre.rossi@gmail.com>
* Gracefully handle requests/responses without data.Milian Wolff2013-11-012-2/+2
| | | | | Change-Id: I269ded913b25bb3d3869f2da85ce0ff7449b534b Reviewed-by: Pierre Rossi <pierre.rossi@gmail.com>
* Add support for websocket ping/pongs.Milian Wolff2013-11-015-2/+16
| | | | | Change-Id: Id825cc0095398d72922700fa5c0d4f30cf19353c Reviewed-by: Pierre Rossi <pierre.rossi@gmail.com>
* Add support for Q_ENUMS access via the web channel.Milian Wolff2013-11-012-0/+14
| | | | | | | | Enums that are marked by Q_ENUMS in a Q_OBJECT or Q_GADGET are thus accessible in JavaScript via obj.EnumName.EnumKey. Change-Id: Ia3e92da9bc05e06011f250ec8f5cf6ac26a3b0f4 Reviewed-by: Pierre Rossi <pierre.rossi@gmail.com>