Serving QML applications over the network
-
Upload
jeremy-laine -
Category
Technology
-
view
3.694 -
download
3
description
Transcript of Serving QML applications over the network
![Page 1: Serving QML applications over the network](https://reader034.fdocuments.in/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.fdocuments.in/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.fdocuments.in/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.fdocuments.in/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.fdocuments.in/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.fdocuments.in/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.fdocuments.in/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.fdocuments.in/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.fdocuments.in/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.fdocuments.in/reader034/viewer/2022052304/558d31fad8b42ac1268b47a1/html5/thumbnails/10.jpg)
10
2. QML network transparency
![Page 11: Serving QML applications over the network](https://reader034.fdocuments.in/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.fdocuments.in/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.fdocuments.in/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.fdocuments.in/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.fdocuments.in/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.fdocuments.in/reader034/viewer/2022052304/558d31fad8b42ac1268b47a1/html5/thumbnails/16.jpg)
16
3. Building your application
![Page 17: Serving QML applications over the network](https://reader034.fdocuments.in/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.fdocuments.in/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.fdocuments.in/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.fdocuments.in/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.fdocuments.in/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.fdocuments.in/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.fdocuments.in/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.fdocuments.in/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.fdocuments.in/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.fdocuments.in/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.fdocuments.in/reader034/viewer/2022052304/558d31fad8b42ac1268b47a1/html5/thumbnails/27.jpg)
27
4. Deploying your application
![Page 28: Serving QML applications over the network](https://reader034.fdocuments.in/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.fdocuments.in/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.fdocuments.in/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.fdocuments.in/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.fdocuments.in/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.fdocuments.in/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.fdocuments.in/reader034/viewer/2022052304/558d31fad8b42ac1268b47a1/html5/thumbnails/34.jpg)
34
5. Questions
![Page 35: Serving QML applications over the network](https://reader034.fdocuments.in/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