Lab : Test du AMF server de Zend Framework 1.7 (Partie Actionscript)

Moins rose que le coté PHP mais tout aussi facile !

Mise en place

Pour la partie coté serveur cf l'article "Test du AMF server de Zend Framework 1.7 (Partie PHP)".

En gros ça fonctionne comme pour instancier un objet NetConnection normal à peu de choses près :

  • établir la communication AMF over http entre flash et php ;
  • définir les comportements de bases (gestion des events, des callbacks,...) ;
  • vérifier le typage et la structure des variables après désérialisation AMF de chaque coté (Actionscript > PHP et PHP > Actionscript).

La partie PHP est expliquée via le lab PHP dans "Test du AMF server de Zend Framework 1.7 (Partie PHP)" smiley myconcept:actionscript & php développement et management pour applications RIA (internet, intranet et extranet).


Voici le code de base : rien d'extraordinaire si ce n'est que quasi rien n'est géré (statut link , erreurs,...).

/ **
* Display the netconnection status events
* @param   NetStatusEvent   e   
* @return  void
* /
function onNCStatus(e:NetStatusEvent):void {
    trace("---- Link Status ----");
    for(var k in e){ trace(e+">"+e[k]);    }
    trace("-------------");
}
/ **
* Display  the netconnection  errors
* @param   mixed : IO_ERROR / SECURITY_ERROR   e   
* @return  void
*  /
function onNCError(e:*):void {
    trace("---- Link Error ----");
    for(var k in e){ trace(e+">"+e[k]);   }
    trace("-------------");
}
/ *
* Display  the server replies
* @param   mixed    reply       object, string, number, etc replied from server  
* @return  void
* /
function onNRSuccess(reply:*):void{
    trace(">> Server Reply ");
}
/ *
* Display  the server errors
* @param   mixed    reply       object containing the error
* @return  void
* /
function onNRError(error:Object):void{
    trace(">> Server Error : "+error.description);
}
var uri:String = "http://localhost/lab/amf_server.php";
var nc:NetConnection = new NetConnection;
var nr:Responder = new Responder(onNRSuccess, onNRError);
nc.addEventListener(NetStatusEvent.NET_STATUS,onNCStatus);
nc.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onNCError);
nc.addEventListener(IOErrorEvent.IO_ERROR, onNCError);
nc.connect(uri);
nc.call("Test.say", nr, "Good Morning Sir !");
nc.call("Test.getBoolean",nr);
nc.call("Test.getObject",nr);

Comportements

Lors des appels

  • L'appel connect() ne provoquera aucun event seuls les calls provoqueront une erreur; L'url n'est d'ailleurs pas appelée. Apparemment ça ne fonctionne (events de connexion, IO_ERROR, security_error) correctement qu'en rtmp car je n'ai eu aucun event.
  • L'appel call si le serveur http renvoie un 404 provoquera une NetStatusEvent 'NetConnection.Call.Failed' avec comme description 'HTTP: Status 404' mais seulement pour le premier call si vous faites plusieurs call un à la suite de l'autre. Ex :
        //Ne générera qu'un seul NetConnection.Call.Failed
        nc.call('Test.say', responder, 'Good Morning Sir ! ');
        nc.call('Test.getBoolean',nr);
        nc.call('Test.getObject',nr);
        nc.call('Test.getArray',nr);
        nc.call('Test.getComplexArray',nr);
        

    Par contre si vous espacez les calls (par exemple dans une boucle) là il y a bien un event d'erreur pour un appel de la méthode.

        //Va générer un NetConnection.Call.Failed par appel
        function engine(e:TimerEvent){
    	   nc.call('Test.say', nr, 'Tick ! ');
        }
        var clock:Timer=new Timer(1000);
        clock.addEventListener(TimerEvent.TIMER,engine);
        clock.start();
        
  • Un truc 'amusant' c'est que si vous avez une erreur php (par exemple de parsing), Flash va détecter une erreur 500... j'ai généré une erreur de parsing et j'ai reçu 'NetConnection.Call.Failed' avec comme description HTTP: Status 500.
  • Si le serveur HTTP répond mais renvoit par exemple 'FooBar' et non pas une erreur PHP, aucune erreur ne sera générée coté flash mais heureusement je n'ai remarqué aucune montée en charge qui aurait pu être issue d'un empilement des requêtes. Donc si vous voulez être certain que le message a bien été envoyé et que la passerelle (l'url) est bien un AMF server et non un message d'erreur ou autre, vous devez gérer la réponse à chaque fois.
  • Si vous appelez une méthode qui n'existe pas vous avez bien une faute dans l'objet Responder que vous avez passé en paramètre au call ('onNRError' dans mon exemple).
  • Coté PHP pensez bien à faire un echo du handle() car sinon flash ne recevra jamais de réponse.
  • Si quelque chose est affiché avant la ligne du handle(), ça va générer un NetStatusEvent 'NetConnection.Call.BadVersion'. Ex:
            //Va générer un NetConnection.Call.BadVersion
            $svr=new Zend_Amf_Server();
            $svr->setClass("Test");
            echo "MYCONCEPT RULES";
            echo $svr->handle();
        

Sérialisation / désérialisation d'objets simples

Pour les résultats des tests et les tables de références désérialisation PHP d'éléments Actionscript & désérialisation Actionscript d'éléments PHP via AMF cf l'article sur le test de AMF server de Zend Framework 1.7 (Partie PHP)

Conclusion de ce petit test de prise en main

En gros ça fonctionne et le mettre en place est un jeu d'enfant. On regrettera cependant tous les events que l'on peut gérer avec un serveur Flash Media en RTMP et qui sont absents ici. On regrettera aussi le fait que le serveur, ou plutôt le service, AMF avec la limite de l'HTTP et une config sans mémoire partagée, ne puisse recevoir qu'un seul client par session. Mais bon faire des échanges AMF gratuitement, sur le port 80, et avec une telle facilité je trouve ça déjà pas mal.


Ce service couplé au 'faux streaming' en PHP de flv, mp3 et mp4 (h264) permettra de faire déjà pas mal de trucs sympas pour la diffusion de médias (on restera quand même loin des fonctionnalités d'un Flash Media Server (enregistrement de lives, diffusions de live,...)).

Le développement de ce service autour d'un socket server serait quand même plus facile pour des applications multi-utilisateurs (chat, jeux,...).

NB : Je n'ai pas testé les policy files (crossdomain & co) mais bon s'il en faut un pour l'HTTP et un autre pour les socketXML je suppose qu'il doit y avoir quelque chose de prévu pour l'AMF over HTTP smiley myconcept:actionscript & php développement et management pour applications RIA (internet, intranet et extranet).

- MY Concept FlashPlayer Loader for actionscript demo's and movie/animation player-