Download - Rich Desktop Applications
Rich Desktop Applications
Raphaël Rougeronhttp://www.raphael-rougeron.com
PHP Québec 2008 – Montréal, Canada
e-tef, la version électronique du Test d'Evaluation de Français
● Test des compétences en compréhension et expression en français général
● Exigé dans certains cas par Citoyenneté et Immigration Canada (CIC)
● Lancement de la version électronique en mars 2005
● De nombreux challenges dans sa mise au point !
Architecture e-tef
Serveurd'examens
Client Flash + Zinc
Site webe-tef
SITEF
Dans quels cas utiliser une solution type RDA ?
● Gestion de médias lourds (audio/vidéo)● Besoin d'une capacité de déconnexion et/ou
d'accéder au système de fichiers local● Besoin d'une UI plus riche (ex : traitements
graphiques, cartographie, etc...)● Plus d'efficacité pour l'utilisateur :
– moins de distractions
– interface plus productive
– moins de temps d'attente ?
Rich Desktop Applications :(tentative de) définition
● Applications client / serveur– fortement connectées (web services)
– mais tirant partie des ressources locales● Cross-platform (+ ou -)● Déployables par HTTP
– installation initiale d'un CLR
– déploiement et mises à jour faciles
Librairies AJAX
Flash/Flex
Silverlight
Applets Java
Google Gears
XulRunner
Adobe AIR
.NET (WPF)
Java Web Start
Prism
RIA RDA
XUL + CSS + JS
Les plateformes les plus accessibles aux talents des développeurs web (et les plus cross-
platform) : Adobe AIR et XulRunner
Adobe AIR
● Windows / Mac OS X (bientôt Linux)
● Flash + Actionscript ou Flex + Actionscript ou HTML + CSS + Javascript
● Moteur WebKit
● Support audio / vidéo / PDF
● IDE : Aptana, Flex Builder
● Runtime commun à toutes les applications
● Installation et mise à jour des applications
● Signature d'applications
● Propriétaire...
Pourquoi AIR peut séduire les développeurs Ajax...
● Mêmes compétences requises● Frameworks JS directement exploitables
(jQuery, extjs, dojo, ...)● Réutilisation du code● Prototypage rapide● Intégration OS via une API JS
Hello world – part 1
<?xml version="1.0" encoding="utf-8" standalone="no"?><application xmlns="http://ns.adobe.com/air/application/1.0.M5" appId="demo" version="1.0"> <name>Démo</name> <title/> <description/> <copyright/> <initialWindow> <title/> <content>demo.html</content> <systemChrome>standard</systemChrome> <transparent>false</transparent> <visible>true</visible> </initialWindow></application>
application.xml
Hello world – part 2
<html> <head> <script type="text/javascript" src="AIRAliases.js"></script> </head> <body> <h1>Hello world</h1> </body></html>
demo.html
Réutilisation de code ?
mmmm...
Adobe AIR : API Javascript
● Windows et Chrome● Système de fichiers● Drag n' Drop● Copier/coller
● SQLLite● Monitoring de
connexion● Requêtes HTTP
(classe URLRequest)
var file = new air.File();file.addEventListener(air.Event.SELECT, dirSelected);file.browseForDirectory();function dirSelected(event) {
alert(file.nativePath); }
Adobe AIR
Adobe AIR
Adobe AIR
Adobe AIR
Adobe AIR
Adobe AIR
XulRunner
● Plateforme de développement d'applis XUL● Version stable : 1.8.4 (-> Firefox 1.5)● Windows, Mac, Linux● Moteur Gecko● XUL + CSS + Javascript● IDE : XulBooster (plugin Eclipse)● Open Source
XUL
● XML-based User interface Language
● Ensemble de balises correspondant à des éléments d'interface graphique :
● Contrôles de formulaires● Grilles, arbres● Barres de menus● Barres d'outils
● Démo : XUL périodic table http://www.hevanet.com/acorbin/xul/top.xul
Hello world – part 1
[App]Vendor=R2Name=demoVersion=0.1BuildID=20070330Copyright=NonsenseID=xxx
[Gecko]MinVersion=1.8.1MaxVersion=1.9
application.ini
Hello World : part 2
<?xml version="1.0"?><?xml-stylesheet href="chrome://global/skin/" type="text/css"?><?xml-stylesheet href="chrome://project/skin/main.css" type="text/css" title="Skin"?><!DOCTYPE window SYSTEM "chrome://project/locale/start.dtd"><window
title="&window.title;"xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
style="width:900px;height:700px;margin:0px;padding:0px;" onload="Application.init();">
<h1>Hello World !</h1> </window>
/chrome/content/start.xul
XulRunner : quoi d'autre ?
● Localisation facile● XBL : définition de composants d'interface
réutilisables● XPCOM : création de composants métiers
réutilisables en JS, C, C++, Python● API JS :
– Manipulation d'images
– Système de fichiers
– Drag n' Drop, clipboard
– SQLLite dans la version 1.9
XulRunner
var nsIFilePicker = Components.interfaces.nsIFilePicker;var fp = Components.classes["@mozilla.org/filepicker;1"] .createInstance(nsIFilePicker);fp.init(window, __("chooseDir.filepicker.title"), nsIFilePicker.modeGetFolder);if (fp.show() == nsIFilePicker.returnOK) { this.prefs.setComplexValue("project.userDir",
Components.interfaces.nsILocalFile, fp.file); this.userDir = fp.file; this.start();}
XulRunner
XulRunner
XulRunner
XulRunner
XulRunner
RDA : recommandations
● Indicateurs d'activité ! (loading...)● Raccourcis-clavier, surtout les basiques (tab,
enter, ...)● Implémenter le copier/coller
(et le drag n' drop)● Survol des boutons● Adopter le look & feel des applis desktop
AIR vs. XULRunner
Relations client - serveur
Support des Web Services
AIR::Flex AIR::Ajax XulRunnerXML-RPC + (non-natif) - +SOAP ++ - ++REST +++ +++ +++
REST en résumé
● Utilisation du plein potentiel de HTTP● Ressources et URIs● GET, POST, PUT, DELETE, HEAD, OPTIONS● Codes d'état : 200 OK, 201 Created, 400 Bad
Request, etc...● Représentations des ressources : XML, JSON,
Atom, RSS, ical, CSV...
Penser ressources plutôt qu'actionsGET /postsPOST /posts/addGET /post/get/123POST /posts/update/123POST /posts/delete/123
vs
GET /postsPOST /postsGET /posts/123PUT /posts/123DELETE /posts/123
REST et PHP
● Difficile de trouver des outils RESTful en PHP !● ZF : Zend_Rest_Server n'est pas RESTful...● Symfony, CakePHP, CodeIgniter : pas de réel
support, même si cela reste possible de l'implémenter soi-même
● 2 frameworks RESTful : Konstruct et Tonic, mais encore bien jeunes...
● Faut tout faire soi-même ;)http://www.stato-framework.org
The Rails way : contrôleurs RESTful
$router = new My_Controller_Router_Rewrite();$router->addResource('bookmarks', new My_Controller_Router_Resource( '/users/:username/bookmarks', array('controller' => 'bookmarks',)));return $router;
http://monservice.com/users/raf/bookmarks/xxx.js-> retourne JSON
http://monservice.com/users/raf/bookmarks/xxx.xml-> retourne XML
http://monservice.com/users/raf/bookmarks/xxx-> retourne HTML
class BookmarksController extends My_Controller_Action{ // GET /users/raf/bookmarks public function indexAction() {...} // GET /users/raf/bookmarks/add public function addAction() {...} // GET /users/raf/bookmarks/edit public function editAction() {...} // POST /users/raf/bookmarks public function doPostAction() {...} // GET /user/raf/bookmarks/xxx public function doGetAction() {...} // PUT /user/raf/bookmarks/xxx public function doPutAction() {...} // DELETE /user/raf/bookmarks/xxx public function doDeleteAction() {...}}
?>
Mais attention :class BookmarksController extends My_Controller_Action{ // GET /user/raf/bookmarks/xxx public function getAction() { $this->view->bookmark
= Bookmarks::find($this->__getParam('id')); switch ($this->getRequest()->getFormat()) { case 'xml': $this->renderXml(
$this->view->bookmark->toXml() );
break; case 'atom': ... break; } }}
Mais attention :class BookmarksController extends My_Controller_Action{ // GET /user/raf/bookmarks/xxx public function getAction() { $this->view->bookmark
= Bookmarks::find($this->__getParam('id')); switch ($this->getRequest()->getFormat()) { case 'xml': $this->renderXml(
$this->view->bookmark->toXml() );
break; case 'atom': ... break; } }}
Les contrôleurs peuvent devenir lourds !!!
Responsabilités des contrôleurs
● Création d'objets associés (multiples INSERTs) ?● Validation des paramètres ?● Transactions ?● Envoi de mail, notifications ?
Est-ce vraiment le rôle des contrôleurs ?
Couche Services Ressourcesclass Bookmarks extends SResource{ public function get() {...} public function post() {...} public function put() {...} public function delete() {...}}
● Possibilité d'offrir des points d'entrée SOAP, XML-RPC et REST <methodName>bookmarks.put</methodName>● Utilisation de l'API de Réflexion :
● Typage et validation des paramètres (type hinting)● Génération automatique des fichiers WSDL et WADL
RADAR (Dave Thomas)Rest Application, Dumb-Ass Recipient
ServeurREST
Client Riche
Serveurde pages
Browser
Ressources
Dispatcher
Client riche Navigateur
Controller
View
Des questions ?
Use the Force of Javascript, Luke