Communications avec d’autres occurrences de Flash Player et d’AIR

Flash Player 9 et les versions ultérieures, Adobe AIR 1.0 et les versions ultérieures

La classe LocalConnection assure les communications entre les applications Adobe® AIR®, ainsi qu’entre les contenus SWF qui s’exécutent dans le navigateur. Vous disposez également de la classe LocalConnection pour communiquer entre une application AIR et un contenu SWF qui s’exécute dans le navigateur. La classe LocalConnection permet de développer des applications particulièrement versatiles capables de partager des données entre occurrences de Flash Player et d’AIR.

A propos de la classe LocalConnection

La classe LocalConnection permet de développer des fichiers SWF qui peuvent échanger des instructions avec d’autres fichiers SWF sans utiliser la méthode fscommand() ou JavaScript. Les objets LocalConnection peuvent uniquement communiquer entre des fichiers SWF exécutés sur le même ordinateur client, mais ils peuvent concerner différentes applications. Par exemple, un fichier SWF exécuté dans un navigateur et un fichier SWF de projection peuvent partager des informations, le fichier de projection se chargeant de maintenir les informations locales et le fichier SWF du navigateur se connectant à distance. (un fichier de projection est un fichier SWF enregistré dans un format tel qu’il peut s’exécuter de manière autonome ; il n’est donc pas nécessaire de disposer de Flash Player pour le lire, car il est incorporé dans le fichier exécutable).

Les objets LocalConnection peuvent être utilisés pour communiquer entre des SWF utilisant différentes versions d’ActionScript :

  • Les objets LocalConnection créés dans ActionScript 1.0 ou 2.0 peuvent communiquer avec les objets LocalConnection créés dans ActionScript 3.0.

  • Les objets LocalConnection créés dans ActionScript 1.0 ou 2.0 peuvent communiquer avec les objets LocalConnection créés dans ActionScript 3.0.

Flash Player gère automatiquement les communications entre les objets LocalConnection de versions différentes.

La façon la plus simple d’utiliser un objet LocalConnection consiste à autoriser la communication uniquement entre des objets LocalConnection se trouvant dans le même domaine ou dans la même application AIR. Vous évitez ainsi les problèmes de sécurité. Toutefois, si vous devez autoriser les communications entre les domaines, vous disposez de diverses méthodes pour mettre en œuvre des mesures de sécurité. Pour plus d’informations, voir l’analyse du paramètre connectionName de la méthode send(), ainsi que les entrées allowDomain() et domain dans le code associé à la classe LocalConnection du manuel Guide de référence ActionScript 3.0 pour la plate-forme Adobe Flash.

Il est possible d’utiliser des objets LocalConnection pour envoyer et recevoir des données au sein d’un fichier SWF unique. Toutefois, Adobe ne recommande pas cette pratique. Faites de préférence appel aux objets partagés.

Les méthodes de rappel peuvent être ajoutées aux objets LocalConnection de trois manières :

  • Créer des sous-classes de LocalConnection et ajouter des méthodes

  • Définir la propriété LocalConnection.client sur un objet qui implémente ces méthodes

  • Créer une classe dynamique qui étend la classe LocalConnection et y joindre dynamiquement des méthodes

La première manière d’ajouter des méthodes de rappel est d’étendre la classe LocalConnection. Vous pouvez définir les méthodes au sein de la classe personnalisée, plutôt que de les ajouter dynamiquement à l’occurrence de LocalConnection. Ceci est illustré par le code suivant :.

package 
{ 
    import flash.net.LocalConnection; 
    public class CustomLocalConnection extends LocalConnection 
    { 
        public function CustomLocalConnection(connectionName:String) 
        { 
            try 
            { 
                connect(connectionName); 
            } 
            catch (error:ArgumentError) 
            { 
                // server already created/connected 
            } 
        } 
        public function onMethod(timeString:String):void 
        { 
            trace("onMethod called at: " + timeString); 
        } 
    } 
}

Pour créer une occurrence de la classe CustomLocalConnection, vous pouvez utiliser le code suivant :

var serverLC:CustomLocalConnection; 
serverLC = new CustomLocalConnection("serverName");

La deuxième manière d’ajouter des méthodes de rappel consiste à utiliser la propriété LocalConnection.client. Il s’agit de créer une classe personnalisée et d’affecter une nouvelle occurrence à la propriété client, comme le montre le code suivant :

var lc:LocalConnection = new LocalConnection(); 
lc.client = new CustomClient();

La propriété LocalConnection.client indique les méthodes de rappel d’objet à appeler. Dans le code précédent la propriété client était définie sur une nouvelle occurrence de la classe personnalisée CustomClient. La valeur par défaut de la propriété client est l’occurrence de LocalConnection actuelle. Vous pouvez utiliser la propriété client si vous disposez de deux gestionnaires de données dotés du même jeu de méthodes mais qui agissent différemment ; par exemple, dans une application où un bouton situé dans une fenêtre permet d’afficher le contenu d’une deuxième fenêtre.

Pour créer la classe CustomClient, vous pouvez utiliser le code suivant :

package 
{ 
    public class CustomClient extends Object 
    { 
        public function onMethod(timeString:String):void 
        { 
            trace("onMethod called at: " + timeString); 
        } 
    } 
}

La troisième manière d’ajouter des méthodes de rappel consiste à créer une classe dynamique et d’y joindre dynamiquement des méthodes. Elle se rapproche de l’utilisation de la classe LocalConnection dans les versions précédentes d’ActionScript, comme le montre le code suivant :

import flash.net.LocalConnection; 
dynamic class DynamicLocalConnection extends LocalConnection {}

Les méthodes de rappel peuvent être ajoutées dynamiquement à cette classe à l’aide du code suivant :

var connection:DynamicLocalConnection = new DynamicLocalConnection(); 
connection.onMethod = this.onMethod; 
// Add your code here. 
public function onMethod(timeString:String):void 
{ 
    trace("onMethod called at: " + timeString); 
}

Cette manière d’ajouter des méthodes de rappel est déconseillée, car le code n’est pas vraiment portable. En outre, cette méthode de création de connexions locales pourrait présenter des problèmes de performance car l’accès aux propriétés dynamiques prend bien plus de temps que l’accès aux propriétés scellées.

Propriété isPerUser

La propriété isPerUser a été intégrée à Flash Player (10.0.32) et AIR (1.5.2) pour résoudre un conflit qui se produit lorsque plusieurs utilisateurs ont ouvert une session sur un ordinateur Mac. Elle n’est pas prise en charge par les autres systèmes d’exploitation, car seuls des utilisateurs spécifiques sont autorisés à se connecter localement. Définissez la propriété isPerUser sur true dans le nouveau code. Actuellement, la valeur par défaut correspond toutefois à false à des fins de compatibilité ascendante. Elle sera peut-être modifiée dans les versions futures des moteurs d’exécution.

Envoi de messages entre deux applications

Vous pouvez utiliser la classe LocalConnection pour communiquer d’une part entre différentes applications AIR et, d’autre part, entre différentes applications Adobe® Flash® Player (SWF) qui s’exécutent dans un navigateur. Vous disposez également de la classe LocalConnection pour communiquer entre une application AIR et une application SWF qui s’exécute dans un navigateur.

Par exemple, vous pouvez utiliser plusieurs occurrences de Flash Player sur une même page Web ou vous servir d’une occurrence de Flash Player pour récupérer des données dans une occurrence de Flash Player affichée dans une fenêtre distincte.

Le code ci-dessous définit un objet LocalConnection qui joue le rôle d’un serveur et qui accepte des appels LocalConnection provenant d’autres applications :
package 
{ 
    import flash.net.LocalConnection; 
    import flash.display.Sprite; 
    public class ServerLC extends Sprite 
    { 
        public function ServerLC() 
        { 
            var lc:LocalConnection = new LocalConnection(); 
            lc.client = new CustomClient1(); 
            try 
            { 
                lc.connect("conn1"); 
            } 
            catch (error:Error) 
            { 
                trace("error:: already connected"); 
            } 
        } 
    } 
}

Ce code crée un objet LocalConnection appelé lc et définit la propriété client sur une classe clientObject. Lorsqu’une autre application appelle une méthode dans cette occurrence de LocalConnection, le moteur d’exécution recherche cette méthode dans l’objet clientObject.

Si une connexion portant le nom spécifié est déjà établie, une exception Argument Error est renvoyée, ce qui indique que la tentative de connexion a échoué parce que l’objet était déjà connecté.

Dès qu’une occurrence de Flash Player se connecte à ce fichier SWF et essaie d’appeler l’une des méthodes de la connexion local, la requête est envoyée à la classe spécifiée par la propriété client, à savoir la classe CustomClient1 :

package 
{ 
    import flash.events.*; 
    import flash.system.fscommand; 
    import flash.utils.Timer; 
    public class CustomClient1 extends Object 
    { 
        public function doMessage(value:String = ""):void 
        { 
            trace(value); 
        } 
        public function doQuit():void 
        { 
            trace("quitting in 5 seconds"); 
            this.close(); 
            var quitTimer:Timer = new Timer(5000, 1); 
            quitTimer.addEventListener(TimerEvent.TIMER, closeHandler); 
        } 
        public function closeHandler(event:TimerEvent):void 
        { 
            fscommand("quit"); 
        } 
    } 
}

Pour créer un serveur LocalConnection, appelez la méthode LocalConnection.connect() et fournissez un nom de connexion unique. Si une connexion est déjà ouverte avec le nom choisi, une erreur ArgumentError est générée, ce qui indique que la tentative de connexion a échoué parce que l’objet était déjà connecté.

L’extrait de code suivant illustre comment créer une LocalConnection appelée conn1 :
try 
{ 
    connection.connect("conn1"); 
} 
catch (error:ArgumentError) 
{ 
    trace("Error! Server already exists\n"); 
}
La connexion à l’application principale à partir d’une application secondaire nécessite que vous créiez d’abord un objet LocalConnection dans l’objet LocalConnection d’envoi, puis que vous appeliez la méthode LocalConnection.send() avec le nom de la connexion et le nom de la méthode à exécuter. Par exemple, pour envoyer la méthode doQuit à l’objet LocalConnection créé précédemment, utilisez le code suivant :
sendingConnection.send("conn1", "doQuit");

Ce code établit une connexion conn1 à l’objet LocalConnection existant, puis appelle la méthode doMessage() dans l’application distante. Si vous souhaitez envoyer des paramètres à l’application distante, spécifiez les arguments supplémentaires après le nom de la méthode send(), comme le montre l’extrait de code suivant :

sendingConnection.send("conn1", "doMessage", "Hello world");

Connexion au contenu dans des domaines différents et aux applications AIR

Pour autoriser uniquement les communications issues de domaines précis, appelez la méthode allowDomain() ou allowInsecureDomain() de la classe LocalConnection et transmettez la liste des domaines autorisés à accéder à cet objet LocalConnection.

Dans les versions antérieures d’ActionScript, LocalConnection.allowDomain() et LocalConnection.allowInsecureDomain() étaient des méthodes de rappel que les développeurs devaient implémenter et qui devaient renvoyer une valeur booléenne. Dans ActionScript 3.0, LocalConnection.allowDomain() et LocalConnection.allowInsecureDomain() sont deux méthodes intégrées, que les développeurs peuvent appeler de la même façon que Security.allowDomain() et Security.allowInsecureDomain(), en transmettant un ou plusieurs noms de domaines à autoriser.

Dans Flash Player 8, des restrictions de sécurité relatives aux fichiers SWF locaux ont été introduites. Un fichier SWF autorisé à accéder à Internet n’a pas accès au système de fichiers local. Si vous spécifiez localhost, tout fichier SWF local peut accéder à ce fichier SWF. Si la méthode LocalConnection.send() tente de communiquer avec un fichier SWF à partir d’un sandbox de sécurité auquel le code d’appel n’a pas accès, un événement securityError (SecurityErrorEvent.SECURITY_ERROR) est distribué. Pour contourner cette erreur, vous pouvez spécifier le domaine de l’appelant dans la méthode LocalConnection.allowDomain() du destinataire.

Deux valeurs spéciales peuvent être transmises aux méthodes LocalConnection.allowDomain() et LocalConnection.allowInsecureDomain() : * et localhost. L’astérisque (*) permet un accès à partir de tous les domaines. La chaîne localhost autorise les appels à l’application à partir du contenu installé localement mais hors du répertoire des ressources de l’application.

Si la méthode LocalConnection.send() essaie de communiquer avec une application à partir d’un sandbox de sécurité auquel le code d’appel n’a pas accès, un événement securityError (SecurityErrorEvent.SECURITY_ERROR) est distribué. Pour contourner cette erreur, vous pouvez spécifier le domaine de l’appelant dans la méthode LocalConnection.allowDomain() du destinataire.

Si vous mettez en œuvre la communication uniquement entre contenus du même domaine, vous pouvez spécifier un paramètre connectionName qui ne commence pas par un caractère de soulignement (_) et ne spécifie pas un nom de domaine (par exemple myDomain:connectionName). Utilisez la même chaîne dans la commande LocalConnection.connect(connectionName).

Si vous mettez en œuvre la communication entre contenus de domaines différents, spécifiez un paramètre connectionName qui commence par un caractère de soulignement. L’ajout d’un caractère de soulignement améliore la portabilité entre domaines du contenu qui possède l’objet LocalConnection de réception. Les deux cas de figure possibles sont les suivants :

  • Si la chaîne associée à connectionName ne commence pas par un caractère de soulignement, le moteur d’exécution ajoute un préfixe au nom du superdomaine suivi de deux points, comme dans myDomain:connectionName. Vous avez ainsi la garantie que votre connexion n’entrera pas en conflit avec les connexions de même nom dans d’autres domaines. Mais tous les objets LocalConnection d’envoi doivent spécifier ce superdomaine, comme dans myDomain:connectionName. Si le fichier HTML ou SWF associé à l’objet LocalConnection de réception est déplacé vers un autre domaine, le moteur d’exécution modifie le préfixe afin qu’il reflète le nouveau superdomaine, comme dans anotherDomain:connectionName. Tous les objets LocalConnection d’envoi doivent être modifiés manuellement pour pointer vers le nouveau superdomaine.

  • Si la chaîne associée à connectionName commence par un caractère de soulignement, comme dans _connectionName), le moteur d’exécution ne lui ajoute pas de préfixe. Les objets LocalConnection de réception et d’envoi utilisent donc des chaînes identiques pour connectionName. Si l’objet de réception utilise LocalConnection.allowDomain() pour spécifier que les connexions seront acceptées à partir de tous les domaines, le fichier HTML ou SWF contenant l’objet LocalConnection de réception peut être déplacé vers un autre domaine, sans qu’il soit nécessaire de modifier les objets LocalConnection d’envoi.

    Il existe un inconvénient à utiliser des noms avec caractère de soulignement dans connectionName : c’est le risque de collision. Deux applications peuvent tenter de se connecter à l’aide du même connectionName. Il en existe un deuxième lié à la sécurité. Les noms de connexion qui utilisent la syntaxe du caractère de soulignement n’identifient pas le domaine de l’application à l’écoute. C’est pour ces raisons qu’il est préférable de recourir à des noms dotés de qualificatifs de domaines.

Adobe AIR

Pour communiquer avec le contenu qui s’exécute dans le sandbox de sécurité de l’application AIR (contenu installé avec l’application AIR), vous devez insérer avant le nom de connexion un superdomaine qui identifie l’application AIR. La chaîne du superdomaine commence par app#, suivi de l’identifiant d’application, suivi d’un point (.), suivi de l’identifiant d’éditeur (s’il est défini). Ainsi, le superdomaine adapté au paramètre connectionName si l’identifiant d’application est com.example.air.MyApp et qu’aucun identifiant d’éditeur n’est stipulé, correspond à : « app#com.example.air.MyApp ». Par conséquent, si le nom de la connexion de base est « appConnection », la chaîne entière à utiliser dans le paramètre connectionName correspond à : « app#com.example.air.MyApp:appConnection ». Si l’application stipule l’identifiant d’éditeur, ce dernier doit être inclus dans la chaîne du superdomaine, comme suit : « app#com.example.air.MyApp.B146A943FBD637B68C334022D304CEA226D129B4.1 ».

Lorsque vous autorisez une autre application AIR à communiquer avec votre application via la connexion locale, vous devez appeler l’élément allowDomain() de l’objet LocalConnection en transmettant le nom du domaine de la connexion locale. Pour une application AIR, ce nom de domaine est formé à partir des ID d’application et d’éditeur, de la même façon que la chaîne de connexion. Par exemple, si l’application AIR d’envoi a pour ID d’application com.example.air.FriendlyApp et pour ID d’éditeur 214649436BD677B62C33D02233043EA236D13934.1, la chaîne de domaine que vous utiliseriez pour autoriser cette application à se connecter est : app#com.example.air.FriendlyApp.214649436BD677B62C33D02233043EA236D13934.1. (Depuis la version 1.5.3 d’AIR, certaines applications AIR ne possèdent pas d’identifiant d’éditeur.)