serving qml applications over the network
DESCRIPTION
Qt Quick's support for network transparency makes it possible to serve an application's user interface and logic over the network. This allows application developers to adopt fast web-like release cycles, but it does require some planning ahead. The presentation will highlight some benefits of serving QML applications over the network, give an overview of QML's network transparency support and illustrate how to build and serve QML applications. The presentation will also address some of the challenges encountered in a real world application deployment.TRANSCRIPT
![Page 1: Serving QML applications over the network](https://reader034.vdocuments.mx/reader034/viewer/2022052304/558d31fad8b42ac1268b47a1/html5/thumbnails/1.jpg)
Serving QML applications over the network
Jeremy LainéWifirst
![Page 2: Serving QML applications over the network](https://reader034.vdocuments.mx/reader034/viewer/2022052304/558d31fad8b42ac1268b47a1/html5/thumbnails/2.jpg)
2 / 35
Jeremy Lainé
●Using Qt since 2001 (desktop, mobile, embedded)
●Occasional Qt contributor (QDnsLookup)
●Head of software development at Wifirst (ISP)
●Lead developer of a IM / VoIP app for Wifirst customers
![Page 3: Serving QML applications over the network](https://reader034.vdocuments.mx/reader034/viewer/2022052304/558d31fad8b42ac1268b47a1/html5/thumbnails/3.jpg)
3 / 35
Overview
1. Why serve applications over the network?
2. QML network transparency
3. Building your application
4. Deploying your application
![Page 4: Serving QML applications over the network](https://reader034.vdocuments.mx/reader034/viewer/2022052304/558d31fad8b42ac1268b47a1/html5/thumbnails/4.jpg)
4
1. Why serve applications over the network?
![Page 5: Serving QML applications over the network](https://reader034.vdocuments.mx/reader034/viewer/2022052304/558d31fad8b42ac1268b47a1/html5/thumbnails/5.jpg)
Typical application deployment
●Development
●Packaging
●In-house beta testing
●Push application to all users
●Repeat!
Each iteration requires per-platform installers and an update.Each iteration requires per-platform installers and an update.
![Page 6: Serving QML applications over the network](https://reader034.vdocuments.mx/reader034/viewer/2022052304/558d31fad8b42ac1268b47a1/html5/thumbnails/6.jpg)
6 / 35
Options for handling updates
●Manual updates●Most users cannot be bothered to update
●You end up with a heterogeneous installed base●Your cool new features don't reach your users!
●Automatic updates●Not all platforms have an “application store”
●Each platform requires specific packaging wok
●Usually requires elevated permissions (Windows UAC..)
![Page 7: Serving QML applications over the network](https://reader034.vdocuments.mx/reader034/viewer/2022052304/558d31fad8b42ac1268b47a1/html5/thumbnails/7.jpg)
7 / 35
Updates are hard!
Not convinced? Look at the Chrome and Firefox codebases!Not convinced? Look at the Chrome and Firefox codebases!
![Page 8: Serving QML applications over the network](https://reader034.vdocuments.mx/reader034/viewer/2022052304/558d31fad8b42ac1268b47a1/html5/thumbnails/8.jpg)
8 / 35
How about QML apps?
●C++ wrapper code:● has usual deployment constraints
●QML / Javascript code and resources:●fully cross-platform
●conveniently split into multiple files
●can be loaded over the network by QtQuick
![Page 9: Serving QML applications over the network](https://reader034.vdocuments.mx/reader034/viewer/2022052304/558d31fad8b42ac1268b47a1/html5/thumbnails/9.jpg)
9 / 35
Some benefits
●Faster iteration and testing
●Fix bugs after release!
●Progressive update roll-out
●Split testing for UI changes
●Time-limited changes (Christmas specials!)
![Page 10: Serving QML applications over the network](https://reader034.vdocuments.mx/reader034/viewer/2022052304/558d31fad8b42ac1268b47a1/html5/thumbnails/10.jpg)
10
2. QML network transparency
![Page 11: Serving QML applications over the network](https://reader034.vdocuments.mx/reader034/viewer/2022052304/558d31fad8b42ac1268b47a1/html5/thumbnails/11.jpg)
11 / 35
Loading QML from C++
QDeclarativeView (Qt4) and QQuickView (Qt5) support loading from an HTTP URL
int main(int argc, char *argv[]){ QApplication app(argc, argv);
QQuickView view; view.setSource(QUrl(“http://foo.com/main.qml”)); view.show();
return app.exec();}
![Page 12: Serving QML applications over the network](https://reader034.vdocuments.mx/reader034/viewer/2022052304/558d31fad8b42ac1268b47a1/html5/thumbnails/12.jpg)
12 / 35
QML “loader” elements
Built-in QML elements with a “source” property support HTTP URLs
●Image
●Loader
●FontLoader
Image { source: “http://foo.com/bar.img”}
![Page 13: Serving QML applications over the network](https://reader034.vdocuments.mx/reader034/viewer/2022052304/558d31fad8b42ac1268b47a1/html5/thumbnails/13.jpg)
13 / 35
Relative URLs
Relative URLs are resolved relative to the QML document's URL
You can use the same code locally and remotely!You can use the same code locally and remotely!
Image { source: “head.jpg”}
file:///home/bob/foo.qml
Image { source: “head.jpg”}
http://example.com/foo.qml
file:///home/bob/head.jpg
http://example.com/head.jpg
![Page 14: Serving QML applications over the network](https://reader034.vdocuments.mx/reader034/viewer/2022052304/558d31fad8b42ac1268b47a1/html5/thumbnails/14.jpg)
14 / 35
QML network transparency
●QML type declarations can be served over HTTP, but you need to list your types in a “qmldir” file:
●Javascript code can be served over HTTP
Button 1.0 Button.qmlCheckBox 1.0 CheckBox.qml
import “scripts/utils.js” as Utils
![Page 15: Serving QML applications over the network](https://reader034.vdocuments.mx/reader034/viewer/2022052304/558d31fad8b42ac1268b47a1/html5/thumbnails/15.jpg)
15 / 35
Translations
●Loading translations from QML is missing
●You can provide your own TranslationLoader and do
●A proposal for including it in Qt5
https://codereview.qt-project.org/#change,31864
TranslationLoader {source: “i18n/my_translation.qm”
onStatusChanged: {Console.log(“status is: “ + status);
}}
![Page 16: Serving QML applications over the network](https://reader034.vdocuments.mx/reader034/viewer/2022052304/558d31fad8b42ac1268b47a1/html5/thumbnails/16.jpg)
16
3. Building your application
![Page 17: Serving QML applications over the network](https://reader034.vdocuments.mx/reader034/viewer/2022052304/558d31fad8b42ac1268b47a1/html5/thumbnails/17.jpg)
17 / 35
General recommendations
●Split models and presentation
●The C++ code still needs traditional updates●Make the loader robust
●Keep the API simple
●Keep the API stable
●Serve all the rest on the fly●QML and Javascript code
●Resources (images, fonts, translations)
![Page 18: Serving QML applications over the network](https://reader034.vdocuments.mx/reader034/viewer/2022052304/558d31fad8b42ac1268b47a1/html5/thumbnails/18.jpg)
18 / 35
Application architecture
Application Plugins
main.qml
Button.qml
background.png
fontawesome.ttf
Local C++ code
Remote content
![Page 19: Serving QML applications over the network](https://reader034.vdocuments.mx/reader034/viewer/2022052304/558d31fad8b42ac1268b47a1/html5/thumbnails/19.jpg)
19 / 35
The application
●Creates the QML view
●Sets up the QNetworkAccessManager
●Loads a single “root” QML file over the network
●Can fallback to local files for offline use
![Page 20: Serving QML applications over the network](https://reader034.vdocuments.mx/reader034/viewer/2022052304/558d31fad8b42ac1268b47a1/html5/thumbnails/20.jpg)
20 / 35
Application / setting up QNAM
●Give your application a User-Agent●Helps track usage, or serve different content
●QtWebkit generated request already have a UA
●Specify the preferred language (Accept-Language)
●Set up a persistent network cache
●Configure HTTP pipelining
![Page 21: Serving QML applications over the network](https://reader034.vdocuments.mx/reader034/viewer/2022052304/558d31fad8b42ac1268b47a1/html5/thumbnails/21.jpg)
21 / 35
Application / caching
●QtQuick caches components + pixmaps (memory)
●QNAM supports “If-Modified-Since” but needs a persistent disk cache
class MyFactory : public QQmlNetworkAccessManagerFactory{public: QNetworkAccessManager* create(QObject* parent) { QNetworkAccessManager* manager = new QNetworkAccessManager(parent); QNetworkDiskCache* cache = new QNetworkDiskCache(manager); cache->setCacheDirectory(“/some/directory/”); manager->setCache(cache); return manager; }};
view->engine()->setNetworkAccessManagerFactory(new MyFactory());
![Page 22: Serving QML applications over the network](https://reader034.vdocuments.mx/reader034/viewer/2022052304/558d31fad8b42ac1268b47a1/html5/thumbnails/22.jpg)
22 / 35
Application / HTTP pipelining
●Splitting QML into files: good but incurs overhead
●HTTP/1.1 allows sending multiple requests without waiting for replies
●Particularly useful for high latency links
●Qt5 uses pipelining for all resources
●Qt4 only uses pipelining for pixmaps and fonts● subclass QNetworkAccessManager if needed
![Page 23: Serving QML applications over the network](https://reader034.vdocuments.mx/reader034/viewer/2022052304/558d31fad8b42ac1268b47a1/html5/thumbnails/23.jpg)
23 / 35
Application / offline use
●At startup, fall back to a bundled copy of your QML code if loading from network fails
●Catching errors later is harder..
void MyView::onStatusChanged(QQuickView::Status status){
if (status == QQuickView::Error && useNetwork) {useNetwork = false;setSource(QUrl(“qrc://main.qml”));
}}
![Page 24: Serving QML applications over the network](https://reader034.vdocuments.mx/reader034/viewer/2022052304/558d31fad8b42ac1268b47a1/html5/thumbnails/24.jpg)
24 / 35
Plugins
●Define data models and scriptable objects
●Keep the C++ code simple : if something can be done in QML instead, do it!
●Keep the API stable : if you change it, you will probably need different QML files
![Page 25: Serving QML applications over the network](https://reader034.vdocuments.mx/reader034/viewer/2022052304/558d31fad8b42ac1268b47a1/html5/thumbnails/25.jpg)
25 / 35
QML content
●Welcome to an asynchronous world!
var component = Qt.createComponent(source);if (component.status == Component.Loading)
component.statusChanged.connect(finishCreation);else
finishCreation();
function finishCreation() {if (component.status == Component.Ready) {
var object = component.createObject(parent);}
}
var component = Qt.createComponent(source);var object = component.createObject(parent); BAD
GOOD
![Page 26: Serving QML applications over the network](https://reader034.vdocuments.mx/reader034/viewer/2022052304/558d31fad8b42ac1268b47a1/html5/thumbnails/26.jpg)
26 / 35
QML content
●Review your timing assumptions!●Do not depend on objects loading in a set order
●Use Component.onCompleted with care
●Having lots of icons can be a problem, consider using web fonts like FontAwesome
![Page 27: Serving QML applications over the network](https://reader034.vdocuments.mx/reader034/viewer/2022052304/558d31fad8b42ac1268b47a1/html5/thumbnails/27.jpg)
27
4. Deploying your application
![Page 28: Serving QML applications over the network](https://reader034.vdocuments.mx/reader034/viewer/2022052304/558d31fad8b42ac1268b47a1/html5/thumbnails/28.jpg)
28 / 35
Hosting the QML code
●You have all the usual web hosting options●Run your own servers (nginx, apache, ..)
●Use cloud services
●Do load-balancing, fail-over, etc..
●QML files can be 100% static files, or even generated on the fly
![Page 29: Serving QML applications over the network](https://reader034.vdocuments.mx/reader034/viewer/2022052304/558d31fad8b42ac1268b47a1/html5/thumbnails/29.jpg)
29 / 35
Version your root URL
●Plan for multiple versions of your C++ app, as the API will probably change, e.g. :
http://example.com/myapp/1.0/main.qml
http://example.com/myapp/1.1/main.qml
●Alternatively, switch on User-Agent
![Page 30: Serving QML applications over the network](https://reader034.vdocuments.mx/reader034/viewer/2022052304/558d31fad8b42ac1268b47a1/html5/thumbnails/30.jpg)
30 / 35
Cache “consistency”
●Consider two related files Dialog.qml and Button.qml, which must be in the same version to work
●Caching can cause inconsistency
Dialog.qmlversion 1
App start 1 App start 2
Button.qmlversion 1
time
Button.qmlversion 1
User click 1 User click 2
Dialog.qmlversion 2
FAIL!
![Page 31: Serving QML applications over the network](https://reader034.vdocuments.mx/reader034/viewer/2022052304/558d31fad8b42ac1268b47a1/html5/thumbnails/31.jpg)
31 / 35
Cache “consistency”
●Your main.qml can load all subsequent contents from a subdirectory to “version” the QML code
●Layout:●main.qml
●RELEASE_ID/Button.qml
●RELEASE_ID/Dialog.qml
![Page 32: Serving QML applications over the network](https://reader034.vdocuments.mx/reader034/viewer/2022052304/558d31fad8b42ac1268b47a1/html5/thumbnails/32.jpg)
32 / 35
Security
●Make use of HTTPS to avoid your application loading malicious code (DNS hijacking)
●Make sure your certificates are valid!
●Some platforms or custom certificates will require adding your CA certificates
QSslSocket::addDefaultCaCertificates(“./myca.pem”);
![Page 33: Serving QML applications over the network](https://reader034.vdocuments.mx/reader034/viewer/2022052304/558d31fad8b42ac1268b47a1/html5/thumbnails/33.jpg)
33 / 35
Performance considerations
●Enable gzip compression for QML and JS files
●Set an Expires header to avoid QNAM re-checking all files on startups
●Serve from a cookie-less domain
![Page 34: Serving QML applications over the network](https://reader034.vdocuments.mx/reader034/viewer/2022052304/558d31fad8b42ac1268b47a1/html5/thumbnails/34.jpg)
34
5. Questions
![Page 35: Serving QML applications over the network](https://reader034.vdocuments.mx/reader034/viewer/2022052304/558d31fad8b42ac1268b47a1/html5/thumbnails/35.jpg)
35 / 35
Get the code
●Source code for the Wifirst IM / VoIP client
git clone git://git.wifirst.net/wilink.git