Hello AFCS ( bye Cocomo ) : première application multi-utilisateurs
[ 5 mars 2009 : Mise à jour de l'article : Cocomo devient AFCS et passe en version 0.9.1, corrigeant quelques bugs ]
Dans ce 1er exemple d’application Cocomo Adobe Flash Collaboration Services aka A.F.C.S, nous allons développer, à vrai dire « assembler », une application de visioconférence intégrant un tchat, des notes partagées et un gestionnaire de partage de fichiers. Pour cela nous allons utiliser des pods, les composants de plus haut-niveau fournis dans cocomo AFCS .
L’un des principaux composants d’une application cocomo AFCS est le gestionnaire de session. C’est lui qui sera chargé de la communication avec les serveurs cocomo AFCS , et donc de l’identification des utilisateurs, de la gestion de leur connexion, de la synchronisation des données… et plus encore…
Deux composants peuvent jouer ce rôle : ConnectSessionContainer et ConnectSession ( tous deux implémentent com.adobe.rtc.session.IConnectSession ).

Hello AFCS ( bye Cocomo )
Pour commencer :
- créer un nouveau projet Flex,
- copier le SWC Cocomo AFCS (depuis CocomoSDK_0.9/lib/player 9 ou 10/afcs.swc) et collez-le dans votre répertoire /libs/
Il s’agit d’un composant basé sur la classe Canvas, et intégrant toute la « mécanique » nécessaire à la communication avec les serveurs cocomo AFCS .
Il est à noter que le ConnectSessionContainer, et donc ses « composants-enfants », resteront invisibles tant que la communication avec salon ne sera pas établie. C’est pour cette raison que nous allons lui intégrer nos pods ( WebCamera, SimpleChat, Notes et FileShare ).Tant que la connexion ne sera pas établie, aucun des composants ne sera visible.
Pour débuter une session, nous devrons renseigner deux propriétés du container de session :
- l’adresse du salon: roomURL ( exemple : http://connectnow.acrobat.com/votreCompte/nomSalon )
- les identifiants de connexion : authenticator
La transmission des identifiants se fait par l’intermédiaire de la classe AdobeHSAuthenticator.Elle a pour fonction d’encapsuler les informations relatives à l’identification( userName, password ). Plusieurs modes d’authentification sont possibles, nous nous y interresserons plus tard.
Dans un premier temps nous nous contenterons d’inscrire nos identifiants « en dur » dans notre application.
On peut noter que les composants liés à AFCS se référent au namespace ‘AfcsNameSpace’ ( anciennement ‘CocomoNameSpace’ dans version 0.9 )
<?xml version="1.0" encoding="utf-8" ?>
<mx:Application layout="absolute"
xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:rtc="AfcsNameSpace"
>
<rtc:ConnectSessionContainer id="sessionManager" width="500" height="400"
roomURL="http://connectnow.acrobat.com/yourAccount/roomName"
authenticator="{identificator}"
backgroundColor="#FFFFFF"
/>
<rtc:AdobeHSAuthenticator id="identificator"
userName="votreLogin" password="VotreMotDePasse"
/>
</mx:Application>
À ce stade, l’application peut déjà se connecter. Par défaut, dès que le connectSessionContainer est créé, il tente d’initier la communication avec les serveurs. Dans cet exemple, j’ai ajouté une couleur de fond pour le container, de manière à pouvoir observer lorsque la connexion au salon est réussie.
Si vous publiez le projet en mode debug vous verrez les logs relatifs aux communications client/serveur.

Pour vérifier si l’authentification est correcte, nous pouvons déclarer des écouteurs d’événements AuthenticationEvent.AUTHENTICATION_FAILURE et AuthenticationEvent.AUTHENTICATION_SUCCESS sur AdobeHSAuthenticator.
Pour capter le moment où notre application est connectée et synchronisée, nous pouvons ajouter un écouteur d’événement SessionEvent.SYNCHRONIZATION_CHANGE sur le container, et surveiller sa propriété ‘isSynchronized‘. Nous reviendrons prochainement sur les différents aspects et acteurs en jeu lors de cette synchronisation.
<?xml version="1.0" encoding="utf-8" ?>
<mx:Application layout="absolute"
xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:rtc="AfcsNameSpace"
>
<mx:Script>
<![CDATA[
import mx.controls.Alert;
import com.adobe.rtc.events.SessionEvent;
// session's state
private var isConnected:Boolean = false;
// when a "server synchronization" event is dispatched
public function onSynchro( e:SessionEvent ):void
{
if ( sessionManager.isSynchronized && ! isConnected )
{
Alert.show("Application connectée");
isConnected = true ;
}
}
]]>
</mx:Script>
<rtc:ConnectSessionContainer id="sessionManager"
width="100%" height="100%" backgroundColor="#FFFFFF"
authenticator="{identificator}"
roomURL="http://connectnow.acrobat.com/regartdemo/meetingzone"
synchronizationChange="onSynchro( event )"
/>
<!-- Authentication component -->
<rtc:AdobeHSAuthenticator id="identificator"
userName="YourUserName" password="YourPassword"
authenticationSuccess="Alert.show('authentication success')"
authenticationFailure="Alert.show('authentication failed')"/>
</mx:Application>
Maintenant que notre connexion parvient à se connecter au salon, nous allons pouvoir intégrer les pods.
Utilisation des pods
Les pods sont des composants collaboratifs « prêt à l’emploi« . Lorsque vous utilisez un ConnectSessionContainer, il suffit d’insérer vos pods à l’intérieur pour qu’ils puissent repérer la connexion établie et l’utiliser.
À ce jour, les pods disponibles sont :
- SimpleChat : composant de « clavardage » permettant l’envoi de messages publics et privés
- WebCamera : composant de visioconférences
- FileShare : composant de partage de fichier ( upload / download )
- Note : composant de partage de notes
- Roster et HorizontalRoster : composant de gestion d’utilisateurs
- SharedWhiteBoard : tableau blanc partagé
Nous allons maintenant insérer les pods souhaités :
<rtc:ConnectSessionContainer id="sessionManager" width="100%" height="100%" backgroundColor="#FFFFFF"
authenticator="{identificator}"
roomURL="http://connectnow.acrobat.com/votreCompte/nomSalon"
synchronizationChange="onSynchro( event )"
>
<!-- PODS -->
<mx:VBox width="50%" height="100%" horizontalAlign="center">
<rtc:WebCamera id="webcam" width="300" />
<rtc:SimpleChat id="chat" width="100%" height="100%" />
</mx:VBox>
<mx:VBox width="50%" height="100%" right="0">
<rtc:FileShare id="fileManager" width="100%" height="50%" />
<rtc:Note id="notes" width="100%" height="50%" />
</mx:VBox>
</rtc:ConnectSessionContainer>

Les pods intégrent des mécanismes de gestion de droits. Nous y reviendrons …
Toujours est-il que voilà, vous avez créé votre première application cocomo AFCS , ou devrais je dire votre première application de « communication en temps réelle ». Mais comment faisait-on avant ???…
Identification et gestion de la connexion aux serveurs
Bon il manque encore quelque chose peut être… Pour un seul utilisateur çà irait presque… mais c’est pas le but :s…Comment fera-t-on si un jour on trouve des amis et qu’on veut collaborer avec eux ??? Tout le monde va se connecter avec le compte « d’admin » ??? Et n’importe quel décompileur AS3 va pouvoir récupérer les identifiants ? Pas très sécure… Heureusement cocomo AFCS nous permet de gérer facilement tous ces aspects.
Les serveurs cocomo AFCS permettent plusieurs types d’identification, notamment une connexion en tant que hôte, basée sur le compte cocomo AFCS Developper, et une connexion en tant qu’invité, ne nécessitant qu’un nom de participant.
Nous allons donc supprimer les attributs userName et password de l’AdobeHSAuthenticator, et ajouter un formulaire d’authentification à notre application. Ce formulaire permettra de choisir le type d’identification ( hôte ou invité ) :
<mx:Panel id="logPanel" >
<mx:Form>
<mx:FormItem label="Login">
<mx:TextInput id="chp_login" />
</mx:FormItem>
<mx:FormItem label="your role :" direction="horizontal" >
<mx:RadioButtonGroup id="userRole" />
<mx:RadioButton id="isGuest" groupName="userRole"
label="Guest" value="{UserRoles.VIEWER}" selected="true"
/>
<mx:RadioButton id="isOwner" groupName="userRole"
label="Host" value="{UserRoles.OWNER}"
/>
</mx:FormItem>
<mx:FormItem label="Password" enabled="{ userRole.selectedValue == UserRoles.OWNER }">
<mx:TextInput id="field_password" displayAsPassword="true" />
</mx:FormItem>
<mx:FormItem >
<mx:Button label="Enter"
click="login(chp_login.text , userRole.selectedValue == UserRoles.OWNER ? field_password.text : null )"
/>
</mx:FormItem>
</mx:Form>
</mx:Panel>
La définition des rôles des utilisateurs est basée sur des valeurs numériques, définies dans des constantes de la classe UserRoles.
Les principaux rôles sont Owner ( hôte / propriétaire du salon ), Publisher ( participant autorisé à publier sur un ou plusieurs pods ) et Viewer ( invité seulement autorisé à utiliser le tchat ). Normallement, les invités ne peuvent utiliser un salon que si l’hôte est présent. Il est possible de modifier la configuration initiale des salons ( droit de publication automatique, persistence des données, entrée libre… ), ainsi que les rôles et les droits des utilisateurs connectés, pour cela nous pourrons utiliser l’application CocomoDevConsole AFCSDevConsole ou l’API directement. Mais c’est déjà une autre histoire…
Pour le moment, nous allons permettre à l’utilisateur de s’identifier à l’aide du formulaire. Pour cela nous devons désactiver la connexion automatique du gestionnaire de session en déclarant sa propriété autoLogin= »false ».
Pour finir, nous allons ajouter une méthode login() qui sera chargée de renseigner le AdobeHSAuthenticator, et de lancer la connexion du gestionnaire de session :
private function login ( login:String, password:String ):void
{
identificator.userName = login;
//if password is set : log as host
//else log as guest
identificator.password = password ;
// run sessionManager connection
sessionManager.login();
}
Nous allons ensuite rajouter un bouton et une fonction de déconnexion.
// disconnection
// in actual 0.9 beta, mostly pods, can't be re-connected after a disconnection
private function logout():void
{
sessionManager.logout();
// close() is supposed to disconnect et remove all childNodes, but seems not work yet
//sessionManager.close();
}
<mx:VBox width="50%" height="100%" horizontalAlign="center" right="0">
<mx:Button label="Logout" click="logout()" />
<rtc:FileShare id="fileManager" width="100%" height="50%" />
<rtc:Note id="notes" width="100%" height="50%" />
</mx:VBox>
Dès que l’application sera connectée, nous supprimerons le formulaire, et en cas de déconnexion le gestionnaire de session sera supprimé :
// for each synchronization event
// : connection, disconnection , state's change, ...
private function onSynchro( e:SessionEvent ):void
{
// once application is successfully connected / synchronized
if ( sessionManager.isSynchronized && ! isConnected )
{
Alert.show("Application connectée");
isConnected = true ;
removeChild( logPanel );
} else if ( ! sessionManager.isSynchronized && isConnected ){
// if disconnected
isConnected = false ;
/* remove the connectSessionContainer
* » in this version disconnected pods can't re-connect
*
* » For re-connect, you can :
* - reload html page
* - dynamically re-create connectSession and pods
*/
removeChild( sessionManager );
// display logout message
Alert.show( 'vous avez quitté la réunion, recharger la page pour entrer à nouveau');
}
}
La gestion des déconnexions / reconnexions semblent pour le moment un peu instables. Mais bon on est prévenu, c’est une béta. Après quelques tests, je crois que le meilleur moyen de revenir dans un salon après s’être déconnecté, est de recharger la page.
Accéder aux sources complétes
Voilà la fin de ce premier exemple d’utilisation de cocomo AFCS , et il est bien entendu possible d’aller beaucoup plus loin. La prochaine fois nous nous intéresserons de plus près aux différents mécanismes articulés au sein de cocomo AFCS , et plus globalement à l’architecture du service. Nous utiliserons également la CocomoDevConsoleAFCSDevConsole et le LocalConnectionServer, les deux outils AIR proposés dans le SDK.
D’ici là bonne collaboration !!!
Tags: cocomo, collaboration, interactivité, tips, Tutoriels

--> 2 février 2009 ( 18:59 )
oh chitte !
Tankiou Erick !
--> 3 février 2009 ( 11:36 )
iu velkom
--> 26 février 2009 ( 0:08 )
Well, as u translated your article in english from flashxpress, i’ll post the same comment but translated cause i think it will be useful:
I got a few articles on my own blog about Cocomo (now AFCS) and someone left an interesting comment:
http://www.flex-tutorial.fr/2008/11/27/adobe-cocomo-installer-le-sdk-adobe-cocomo/#comment-3620
He tried this example with the the SDK (afcs.swc) and his components weren’t recognized. It’s actually a namespace problem, here is the solution
http://www.flex-tutorial.fr/2008/11/27/adobe-cocomo-installer-le-sdk-adobe-cocomo/#comment-3635
In your application tag, just replace xmlns:rtc= »CocomoNameSpace » by xmlns:rtc= »AfcsNameSpace »
Fabien
http://www.flex-tutorial.fr/category/afcs/
--> 6 mars 2009 ( 18:12 )
Thanks
--> 16 avril 2009 ( 13:24 )
Good one. Thanks for sharing.