SlideShare une entreprise Scribd logo
1  sur  35
Télécharger pour lire hors ligne
Serving QML applications over the network




                            Jeremy Lainé
                               Wifirst
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
     2 / 35
Overview



 1. Why serve applications over the network?


 2. QML network transparency


 3. Building your application


 4. Deploying your application

      3 / 35
1. Why serve applications over the network?




                                              4
Typical application deployment


 ●
  Development
 ●
  Packaging
 ●
  In-house beta testing
 ●
  Push application to all users
 ●
  Repeat!

        Each iteration requires per-
        Each iteration requires per-
        platform installers and an update.
        platform installers and an update.
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..)
     ●




         6 / 35
Updates are hard!




       Not convinced? Look at the Chrome
       Not convinced? Look at the Chrome
       and Firefox codebases!
       and Firefox codebases!
     7 / 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
     ●




         8 / 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!)




     9 / 35
2. QML network transparency




                              10
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();
  }


      11 / 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”
                }



      12 / 35
Relative URLs


 Relative URLs are resolved relative to the QML
 document's URL
 Image {
   source: “head.jpg”
 }
   file:///home/bob/foo.qml         file:///home/bob/head.jpg


 Image {
   source: “head.jpg”
 }
   http://example.com/foo.qml      http://example.com/head.jpg

 You can use the same code locally and remotely!
 You can use the same code locally and remotely!
      13 / 35
QML network transparency


 ●
  QML type declarations can be served over HTTP,
 but you need to list your types in a “qmldir” file:
               Button 1.0 Button.qml
               CheckBox 1.0 CheckBox.qml



 ●
  Javascript code can be served over HTTP
          import “scripts/utils.js” as Utils




     14 / 35
Translations

●
 Loading translations from QML is missing
●
 You can provide your own TranslationLoader and do
    TranslationLoader {
       source: “i18n/my_translation.qm”

           onStatusChanged: {
              Console.log(“status is: “ + status);
           }
    }
●
 A proposal for including it in Qt5
 https://codereview.qt-project.org/#change,31864

        15 / 35
3. Building your application




                               16
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)
     ●




         17 / 35
Application architecture


                                   fontawesome.ttf

                  background.png
Remote content
                                                     Button.qml

                                   main.qml




Local C++ code       Application                Plugins




        18 / 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


     19 / 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




         20 / 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());


      21 / 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



         22 / 35
Application / offline use



  At startup, fall back to a bundled copy of your
  ●


  QML code if loading from network fails

void MyView::onStatusChanged(QQuickView::Status status)
{
   if (status == QQuickView::Error && useNetwork) {
      useNetwork = false;
      setSource(QUrl(“qrc://main.qml”));
   }
}


  Catching errors later is harder..
  ●



      23 / 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



     24 / 35
QML content


 ●
  Welcome to an asynchronous world!

var component = Qt.createComponent(source);
var object = component.createObject(parent);           BAD


 var component = Qt.createComponent(source);
 if (component.status == Component.Loading)
    component.statusChanged.connect(finishCreation);
 else
    finishCreation();
                                                       GOOD
 function finishCreation() {
    if (component.status == Component.Ready) {
       var object = component.createObject(parent);
    }
 }

      25 / 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




         26 / 35
4. Deploying your application




                                27
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



         28 / 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




     29 / 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
 App start 1       User click 1          App start 2   User click 2


                         Button.qml                           Button.qml
                          version 1                            version 1   FAIL!

      Dialog.qml                               Dialog.qml
      version 1                                version 2


                                  time
       30 / 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
     ●




         31 / 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”);


        32 / 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




     33 / 35
5. Questions




               34
Get the code




 ●
  Source code for the Wifirst IM / VoIP client



     git clone git://git.wifirst.net/wilink.git




     35 / 35

Contenu connexe

Tendances

Tendances (20)

QtQuick Day 1
QtQuick Day 1QtQuick Day 1
QtQuick Day 1
 
Basics of Model/View Qt programming
Basics of Model/View Qt programmingBasics of Model/View Qt programming
Basics of Model/View Qt programming
 
Best Practices in Qt Quick/QML - Part 2
Best Practices in Qt Quick/QML - Part 2Best Practices in Qt Quick/QML - Part 2
Best Practices in Qt Quick/QML - Part 2
 
Intro to QML / Declarative UI
Intro to QML / Declarative UIIntro to QML / Declarative UI
Intro to QML / Declarative UI
 
Qt test framework
Qt test frameworkQt test framework
Qt test framework
 
QVariant, QObject — Qt's not just for GUI development
QVariant, QObject — Qt's not just for GUI developmentQVariant, QObject — Qt's not just for GUI development
QVariant, QObject — Qt's not just for GUI development
 
Best Practices in Qt Quick/QML - Part 3
Best Practices in Qt Quick/QML - Part 3Best Practices in Qt Quick/QML - Part 3
Best Practices in Qt Quick/QML - Part 3
 
Qt Internationalization
Qt InternationalizationQt Internationalization
Qt Internationalization
 
Best Practices in Qt Quick/QML - Part 4
Best Practices in Qt Quick/QML - Part 4Best Practices in Qt Quick/QML - Part 4
Best Practices in Qt Quick/QML - Part 4
 
Qt for beginners part 4 doing more
Qt for beginners part 4   doing moreQt for beginners part 4   doing more
Qt for beginners part 4 doing more
 
Lockless Producer Consumer Threads: Asynchronous Communications Made Easy
Lockless Producer Consumer Threads: Asynchronous Communications Made EasyLockless Producer Consumer Threads: Asynchronous Communications Made Easy
Lockless Producer Consumer Threads: Asynchronous Communications Made Easy
 
Qt for Beginners Part 3 - QML and Qt Quick
Qt for Beginners Part 3 - QML and Qt QuickQt for Beginners Part 3 - QML and Qt Quick
Qt for Beginners Part 3 - QML and Qt Quick
 
Qt Qml
Qt QmlQt Qml
Qt Qml
 
QThreads: Are You Using Them Wrong?
QThreads: Are You Using Them Wrong? QThreads: Are You Using Them Wrong?
QThreads: Are You Using Them Wrong?
 
Qt multi threads
Qt multi threadsQt multi threads
Qt multi threads
 
Best Practices in Qt Quick/QML - Part 1 of 4
Best Practices in Qt Quick/QML - Part 1 of 4Best Practices in Qt Quick/QML - Part 1 of 4
Best Practices in Qt Quick/QML - Part 1 of 4
 
Fun with QML
Fun with QMLFun with QML
Fun with QML
 
QtQuick Day 2
QtQuick Day 2QtQuick Day 2
QtQuick Day 2
 
Hello, QML
Hello, QMLHello, QML
Hello, QML
 
OpenGL Fixed Function to Shaders - Porting a fixed function application to “m...
OpenGL Fixed Function to Shaders - Porting a fixed function application to “m...OpenGL Fixed Function to Shaders - Porting a fixed function application to “m...
OpenGL Fixed Function to Shaders - Porting a fixed function application to “m...
 

Similaire à Serving QML applications over the network

OpenMP-OpenACC-Offload-Cauldron2022-1.pdf
OpenMP-OpenACC-Offload-Cauldron2022-1.pdfOpenMP-OpenACC-Offload-Cauldron2022-1.pdf
OpenMP-OpenACC-Offload-Cauldron2022-1.pdf
ssuser866937
 

Similaire à Serving QML applications over the network (20)

Webinar - Unbox GitLab CI/CD
Webinar - Unbox GitLab CI/CD Webinar - Unbox GitLab CI/CD
Webinar - Unbox GitLab CI/CD
 
OpenCms Days 2015 Workflow using Docker and Jenkins
OpenCms Days 2015 Workflow using Docker and JenkinsOpenCms Days 2015 Workflow using Docker and Jenkins
OpenCms Days 2015 Workflow using Docker and Jenkins
 
A Browser for the Automotive: Introduction to WebKit for Wayland (Automotive ...
A Browser for the Automotive: Introduction to WebKit for Wayland (Automotive ...A Browser for the Automotive: Introduction to WebKit for Wayland (Automotive ...
A Browser for the Automotive: Introduction to WebKit for Wayland (Automotive ...
 
HTML5 on the AGL demo platform with Chromium and WAM (AGL AMM March 2021)
HTML5 on the AGL demo platform with Chromium and WAM (AGL AMM March 2021)HTML5 on the AGL demo platform with Chromium and WAM (AGL AMM March 2021)
HTML5 on the AGL demo platform with Chromium and WAM (AGL AMM March 2021)
 
Xpdays: Kubernetes CI-CD Frameworks Case Study
Xpdays: Kubernetes CI-CD Frameworks Case StudyXpdays: Kubernetes CI-CD Frameworks Case Study
Xpdays: Kubernetes CI-CD Frameworks Case Study
 
Update on the open source browser space (16th GENIVI AMM)
Update on the open source browser space (16th GENIVI AMM)Update on the open source browser space (16th GENIVI AMM)
Update on the open source browser space (16th GENIVI AMM)
 
Kubernetes 101
Kubernetes 101Kubernetes 101
Kubernetes 101
 
OSDC 2018 | Highly Available Cloud Foundry on Kubernetes by Cornelius Schumacher
OSDC 2018 | Highly Available Cloud Foundry on Kubernetes by Cornelius SchumacherOSDC 2018 | Highly Available Cloud Foundry on Kubernetes by Cornelius Schumacher
OSDC 2018 | Highly Available Cloud Foundry on Kubernetes by Cornelius Schumacher
 
WPEWebKit, the WebKit port for embedded platforms (Linaro Connect San Diego 2...
WPEWebKit, the WebKit port for embedded platforms (Linaro Connect San Diego 2...WPEWebKit, the WebKit port for embedded platforms (Linaro Connect San Diego 2...
WPEWebKit, the WebKit port for embedded platforms (Linaro Connect San Diego 2...
 
JenkinsCI
JenkinsCIJenkinsCI
JenkinsCI
 
Chromium: NaCl and Pepper API
Chromium: NaCl and Pepper APIChromium: NaCl and Pepper API
Chromium: NaCl and Pepper API
 
Andreas Jakl, Qt Symbian Maemo Quickstart
Andreas Jakl, Qt Symbian Maemo QuickstartAndreas Jakl, Qt Symbian Maemo Quickstart
Andreas Jakl, Qt Symbian Maemo Quickstart
 
OpenMP-OpenACC-Offload-Cauldron2022-1.pdf
OpenMP-OpenACC-Offload-Cauldron2022-1.pdfOpenMP-OpenACC-Offload-Cauldron2022-1.pdf
OpenMP-OpenACC-Offload-Cauldron2022-1.pdf
 
To Russia with Love: Deploying Kubernetes in Exotic Locations On Prem
To Russia with Love: Deploying Kubernetes in Exotic Locations On PremTo Russia with Love: Deploying Kubernetes in Exotic Locations On Prem
To Russia with Love: Deploying Kubernetes in Exotic Locations On Prem
 
Extended and embedding: containerd update & project use cases
Extended and embedding: containerd update & project use casesExtended and embedding: containerd update & project use cases
Extended and embedding: containerd update & project use cases
 
DevOpsDays Tel Aviv DEC 2022 | Building A Cloud-Native Platform Brick by Bric...
DevOpsDays Tel Aviv DEC 2022 | Building A Cloud-Native Platform Brick by Bric...DevOpsDays Tel Aviv DEC 2022 | Building A Cloud-Native Platform Brick by Bric...
DevOpsDays Tel Aviv DEC 2022 | Building A Cloud-Native Platform Brick by Bric...
 
ContainerCon - Test Driven Infrastructure
ContainerCon - Test Driven InfrastructureContainerCon - Test Driven Infrastructure
ContainerCon - Test Driven Infrastructure
 
Guided overview of software frameworks qt framework
Guided overview of software frameworks   qt frameworkGuided overview of software frameworks   qt framework
Guided overview of software frameworks qt framework
 
GCP - Continuous Integration and Delivery into Kubernetes with GitHub, Travis...
GCP - Continuous Integration and Delivery into Kubernetes with GitHub, Travis...GCP - Continuous Integration and Delivery into Kubernetes with GitHub, Travis...
GCP - Continuous Integration and Delivery into Kubernetes with GitHub, Travis...
 
WebKit2 And You (GUADEC 2013)
WebKit2 And You (GUADEC 2013)WebKit2 And You (GUADEC 2013)
WebKit2 And You (GUADEC 2013)
 

Dernier

CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
giselly40
 

Dernier (20)

Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?What Are The Drone Anti-jamming Systems Technology?
What Are The Drone Anti-jamming Systems Technology?
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
Tech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdfTech Trends Report 2024 Future Today Institute.pdf
Tech Trends Report 2024 Future Today Institute.pdf
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
CNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of ServiceCNv6 Instructor Chapter 6 Quality of Service
CNv6 Instructor Chapter 6 Quality of Service
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Evaluating the top large language models.pdf
Evaluating the top large language models.pdfEvaluating the top large language models.pdf
Evaluating the top large language models.pdf
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 

Serving QML applications over the network

  • 1. Serving QML applications over the network Jeremy Lainé Wifirst
  • 2. 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 2 / 35
  • 3. Overview 1. Why serve applications over the network? 2. QML network transparency 3. Building your application 4. Deploying your application 3 / 35
  • 4. 1. Why serve applications over the network? 4
  • 5. Typical application deployment ● Development ● Packaging ● In-house beta testing ● Push application to all users ● Repeat! Each iteration requires per- Each iteration requires per- platform installers and an update. platform installers and an update.
  • 6. 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..) ● 6 / 35
  • 7. Updates are hard! Not convinced? Look at the Chrome Not convinced? Look at the Chrome and Firefox codebases! and Firefox codebases! 7 / 35
  • 8. 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 ● 8 / 35
  • 9. Some benefits ● Faster iteration and testing ● Fix bugs after release! ● Progressive update roll-out ● Split testing for UI changes ● Time-limited changes (Christmas specials!) 9 / 35
  • 10. 2. QML network transparency 10
  • 11. 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(); } 11 / 35
  • 12. QML “loader” elements Built-in QML elements with a “source” property support HTTP URLs ● Image ● Loader ● FontLoader Image { source: “http://foo.com/bar.img” } 12 / 35
  • 13. Relative URLs Relative URLs are resolved relative to the QML document's URL Image { source: “head.jpg” } file:///home/bob/foo.qml file:///home/bob/head.jpg Image { source: “head.jpg” } http://example.com/foo.qml http://example.com/head.jpg You can use the same code locally and remotely! You can use the same code locally and remotely! 13 / 35
  • 14. QML network transparency ● QML type declarations can be served over HTTP, but you need to list your types in a “qmldir” file: Button 1.0 Button.qml CheckBox 1.0 CheckBox.qml ● Javascript code can be served over HTTP import “scripts/utils.js” as Utils 14 / 35
  • 15. Translations ● Loading translations from QML is missing ● You can provide your own TranslationLoader and do TranslationLoader { source: “i18n/my_translation.qm” onStatusChanged: { Console.log(“status is: “ + status); } } ● A proposal for including it in Qt5 https://codereview.qt-project.org/#change,31864 15 / 35
  • 16. 3. Building your application 16
  • 17. 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) ● 17 / 35
  • 18. Application architecture fontawesome.ttf background.png Remote content Button.qml main.qml Local C++ code Application Plugins 18 / 35
  • 19. 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 19 / 35
  • 20. 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 20 / 35
  • 21. 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()); 21 / 35
  • 22. 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 22 / 35
  • 23. Application / offline use At startup, fall back to a bundled copy of your ● QML code if loading from network fails void MyView::onStatusChanged(QQuickView::Status status) { if (status == QQuickView::Error && useNetwork) { useNetwork = false; setSource(QUrl(“qrc://main.qml”)); } } Catching errors later is harder.. ● 23 / 35
  • 24. 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 24 / 35
  • 25. QML content ● Welcome to an asynchronous world! var component = Qt.createComponent(source); var object = component.createObject(parent); BAD var component = Qt.createComponent(source); if (component.status == Component.Loading) component.statusChanged.connect(finishCreation); else finishCreation(); GOOD function finishCreation() { if (component.status == Component.Ready) { var object = component.createObject(parent); } } 25 / 35
  • 26. 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 26 / 35
  • 27. 4. Deploying your application 27
  • 28. 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 28 / 35
  • 29. 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 29 / 35
  • 30. Cache “consistency” ● Consider two related files Dialog.qml and Button.qml, which must be in the same version to work ● Caching can cause inconsistency App start 1 User click 1 App start 2 User click 2 Button.qml Button.qml version 1 version 1 FAIL! Dialog.qml Dialog.qml version 1 version 2 time 30 / 35
  • 31. 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 ● 31 / 35
  • 32. 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”); 32 / 35
  • 33. 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 33 / 35
  • 35. Get the code ● Source code for the Wifirst IM / VoIP client git clone git://git.wifirst.net/wilink.git 35 / 35