Conexión con otras instancias de Flash Player y AIR

Flash Player 9 y posterior, Adobe AIR 1.0 y posterior

La clase LocalConnection permite la comunicación entre las aplicaciones de Adobe® AIR®, así como entre el contenido SWF que se ejecuta en el navegador. La clase LocalConnection también se puede utilizar para comunicarse entre una aplicación de AIR y el contenido SWF que se ejecuta en el navegador. La clase LocalConnection permite crear aplicaciones muy versátiles que pueden compartir datos entre instancias de Flash Player y AIR.

Información sobre la clase LocalConnection

La clase LocalConnection permite desarrollar archivos SWF capaces de enviar instrucciones a otros archivos SWF sin utilizar el método fscommand() ni JavaScript. Los objetos LocalConnection solo pueden comunicarse con archivos SWF que se ejecuten en el mismo equipo cliente, aunque pueden ejecutarse en aplicaciones distintas. Por ejemplo, un archivo SWF que se ejecuta en un navegador y un archivo SWF que se ejecuta en un proyector pueden compartir información, y el proyector conserva la información local y el archivo basado en el navegador se conecta de forma remota. (Un proyector es un archivo SWF guardado en un formato que puede ejecutarse como una aplicación autónoma, es decir, que el proyector no requiere que se instale Flash Player porque está incorporado en el ejecutable.)

Los objetos LocalConnection se pueden utilizar para comunicarse entre archivos SWF con distintas versiones de ActionScript:

  • Los objetos LocalConnection de ActionScript 3.0 pueden comunicarse con objetos LocalConnection creados con ActionScript 1.0 o 2.0.

  • Los objetos LocalConnection de ActionScript 1.0 o 2.0 pueden comunicarse con objetos LocalConnection creados con ActionScript 3.0.

Flash Player controla automáticamente esta comunicación entre objetos LocalConnection de distintas versiones.

La manera más simple de utilizar un objeto LocalConnection es permitir la comunicación solo entre objetos LocalConnection ubicados en el mismo dominio o en la misma aplicación de AIR. De este modo no es necesario preocuparse por la seguridad. Sin embargo, si debe permitir la comunicación entre dominios, tiene varias maneras de implementar medidas de seguridad. Para obtener información, consulte la descripción del parámetro connectionName del método send() y las entradas allowDomain() y domain en el listado de clases LocalConnection en Referencia de ActionScript 3.0 para la plataforma de Adobe Flash.

Es posible utilizar objetos LocalConnection para enviar y recibir datos en un solo archivo SWF, pero Adobe no recomienda esta práctica. Utilice objetos compartidos.

Hay tres formas de añadir métodos callback a los objetos LocalConnection:

  • Crear una subclase de la clase LocalConnection y añadir métodos.

  • Establecer la propiedad LocalConnection.client en un objeto que implemente los métodos.

  • Crear una clase dinámica que amplíe LocalConnection y asociar métodos de forma dinámica.

La primera forma de añadir métodos callback consiste en ampliar la clase LocalConnection. Los métodos se definen en la clase personalizada en lugar de añadirlos de forma dinámica a la instancia de LocalConnection. Este enfoque se muestra en el siguiente código:

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

Para crear una nueva instancia de la clase CustomLocalConnection, se puede usar el siguiente código:

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

La segunda forma de añadir métodos callback consiste en utilizar la propiedad LocalConnection.client. Esto implica crear una clase personalizada y asignar una nueva instancia a la propiedad client, como se muestra en el siguiente código:

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

La propiedad LocalConnection.client indica los métodos callback del objeto que deben llamarse. En el código anterior, la propiedad client se estableció en una nueva instancia de una clase personalizada, CustomClient. El valor predeterminado de la propiedad client es la instancia de LocalConnection actual. Se puede utilizar la propiedad client si se tienen dos controladores de datos con el mismo conjunto de métodos pero distintos comportamientos; por ejemplo, en una aplicación donde un botón de una ventana activa o desactiva la visualización en una segunda ventana.

Para crear la clase CustomClient, se podría usar el siguiente código:

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

La tercera forma de añadir métodos callback, que consiste en crear una clase dinámica y asociar los métodos de forma dinámica, es muy similar a la utilización de la clase LocalConnection en versiones anteriores de ActionScript, como se muestra en el siguiente código:

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

Los métodos callback pueden añadirse de forma dinámica a esta clase con el siguiente código:

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

No se recomienda la anterior forma de añadir métodos callback porque el código tiene una escasa portabilidad. Además, si se utiliza este método de creación de conexiones locales, podrían surgir problemas de rendimiento debido a que el acceso a las propiedades dinámicas es considerablemente más lento que el acceso a las propiedades cerradas.

Propiedad isPerUser

La propiedad isPerUser se añadió a Flash Player (10.0.32) y a AIR (1.5.2) para resolver un conflicto que se producía cuando más de un usuario se conectaba a un ordenador Mac. En otros sistemas operativos, esta propiedad se omite porque la conexión local siempre está destinada a usuarios individuales. La propiedad isPerUser debe establecerse como true en código nuevo. Sin embargo, el valor predeterminado es actualmente false para permitir compatibilidad con versiones anteriores. El valor predeterminado puede cambiar en versiones futuras del motor de ejecución.

Envío de mensajes entre dos aplicaciones

Se usa la clase LocalConnection para la comunicación entre aplicaciones de AIR y entre aplicaciones de AIR y aplicaciones de Adobe® Flash® Player (SWF) que se ejecutan en un navegador. La clase LocalConnection también se puede utilizar para comunicarse entre una aplicación de AIR y una aplicación SWF que se ejecuta en un navegador.

Por ejemplo, se pueden tener varias instancias de Flash Player en una página web o se puede hacer que una instancia de Flash Player recupere datos de otra instancia de Flash Player en una ventana emergente.

El siguiente código define un objeto LocalConnection que actúa como un servidor y acepta llamadas entrantes LocalConnection de otras aplicaciones:
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"); 
            } 
        } 
    } 
}

Este código primero crea un objeto LocalConnection denominado lc y define la propiedad client a un objeto clientObject. Cuando otra aplicación llama a un método en esta instancia LocalConnection, el motor de ejecución busca ese método en el objeto clientObject.

Si ya se dispone de una conexión con el nombre especificado, se genera una excepción de error de argumento, que indica que el intento de conexión falló porque el objeto ya está conectado.

Cuando una instancia de Flash Player se conecta a este archivo SWF e intenta llamar a cualquier método en la conexión local especificada, la petición se envía a la clase especificada por la propiedad client, que se establece en la clase 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"); 
        } 
    } 
}

Para crear un servidor LocalConnection, hay que llamar al método LocalConnection.connect() y proporcionar un nombre de conexión exclusivo. Si ya se dispone de una conexión con el nombre especificado, se genera un error ArgumentError, que indica que el intento de conexión falló porque el objeto ya está conectado.

El siguiente fragmento demuestra cómo crear un LocalConnection con el nombre conn1:
try 
{ 
    connection.connect("conn1"); 
} 
catch (error:ArgumentError) 
{ 
    trace("Error! Server already exists\n"); 
}
La conexión a una aplicación principal desde una aplicación secundaria requiere primero crear un objeto LocalConnection en el objeto LocalConnection que se envía y luego llamar al método LocalConnection.send() con el nombre de la conexión y del método para ejecutar. Por ejemplo, para enviar el método doQuit al objeto LocalConnection que ha creado anteriormente, use el siguiente código:
sendingConnection.send("conn1", "doQuit");

Este código se conecta a un objeto LocalConnection existente con el nombre de conexión conn1 e invoca al método doMessage() en la aplicación remota. Si desea enviar parámetros a la aplicación remota, especifique argumentos adicionales después del nombre del método en el método send(), como muestra el siguiente fragmento:

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

Conexión al contenido en diferentes dominios y a otras aplicaciones de AIR

Para permitir la comunicación solo desde dominios específicos, llame al método allowDomain() o allowInsecureDomain() de la clase LocalConnection y pase una lista de uno o más dominios que tienen autorización para acceder al objeto LocalConnection, pasando uno o más nombres de dominios.

En versiones anteriores de ActionScript, LocalConnection.allowDomain() y LocalConnection.allowInsecureDomain() eran métodos callback que implementaban los desarrolladores y que tenían que devolver un valor booleano. En ActionScript 3.0, LocalConnection.allowDomain() y LocalConnection.allowInsecureDomain() son métodos incorporados a los que los desarrolladores llaman del mismo modo que Security.allowDomain() y Security.allowInsecureDomain(), pasando uno o varios nombres de dominios que deben autorizarse.

Flash Player 8 introdujo restricciones de seguridad en los archivos SWF locales. Un archivo SWF al que se le permite acceder a Internet no puede tener también acceso al sistema de archivos local. Si se especifica localhost, cualquier archivo SWF local podrá acceder al archivo SWF. Si el método LocalConnection.send() intenta comunicarse con un archivo SWF desde un entorno limitado de seguridad al que no puede acceder el código que realiza la llamada, se distribuye un evento securityError(SecurityErrorEvent.SECURITY_ERROR). Para solucionar este error, puede especificar el dominio del origen de llamada en el métodoLocalConnection.allowDomain() del receptor.

Hay dos valores especiales que se pueden pasar a los métodos LocalConnection.allowDomain() y LocalConnection.allowInsecureDomain(): * y localhost. El valor de asterisco (*) permite el acceso desde todos los dominios. La cadena localhost permite llamadas a la aplicación desde el contenido localmente instalado, pero fuera del directorio de recursos de la aplicación.

Si el método LocalConnection.send() intenta comunicarse con una aplicación desde un entorno limitado de seguridad al que el código de llamada no tiene acceso, se distribuye un evento securityError(SecurityErrorEvent.SECURITY_ERROR). Para solucionar este error, puede especificar el dominio del origen de llamada en el métodoLocalConnection.allowDomain() del receptor.

Sí solo va a implementar la comunicación entre el contenido del mismo dominio, especifique un parámetro connectionName que no comience por un guion bajo (_) y que no especifique un nombre de dominio (por ejemplo, myDomain:connectionName). Utilice la misma cadena en el comando LocalConnection.connect(connectionName).

Si implementa la comunicación entre contenidos en diferentes dominios, especifique una parámetro connectionName que comienza con un guion bajo. La especificación de los guiones bajos permite que el contenido con el objeto LocalConnection receptor tenga una mayor portabilidad entre dominios. Estos son los dos casos posibles:

  • Si la cadena para connectionName no comienza por un guion bajo, el motor de ejecución añade un prefijo con el nombre del superdominio y dos puntos (por ejemplo, myDomain:connectionName). Aunque esto garantiza que la conexión no entre en conflicto con conexiones de otros dominios que tengan el mismo nombre, los objetos LocalConnection emisores deben especificar este superdominio (por ejemplo, myDomain:connectionName). Si el archivo HTML o SWF que contiene el objeto LocalConnection receptor se traslada a otro dominio, el motor de ejecución cambia el prefijo para reflejar el nuevo superdominio (por ejemplo, anotherDomain:connectionName). Se deben editar manualmente todos los objetos LocalConnection emisores para que apunten al nuevo superdominio.

  • Si la cadena de connectionName comienza por un guion bajo (por ejemplo, _connectionName"), el motor de ejecución no añade un prefijo a la cadena. Esto significa que los objetos LocalConnection receptores y emisores utilizan idénticas cadenas para connectionName. Si el objeto receptor utiliza LocalConnection.allowDomain() para especificar que se acepten las conexiones de cualquier dominio, el SWF que contiene el objeto LocalConnection receptor se puede trasladar a otro dominio sin modificar ningún objeto LocalConnection emisor.

    La desventaja de utilizar nombres con guion bajo en connectionName es la posibilidad de interferencias, como por ejemplo cuando dos aplicaciones intentan conectarse utilizando el mismo connectionName. Una segunda desventaja relacionada se refiere a la seguridad. Los nombres de conexión que usan la sintaxis de guion bajo no identifican el dominio de la aplicación que se detecta. Por estas razones, se prefieren los nombres completos de dominio.

Adobe AIR

Para comunicarse con el contenido ejecutado en el entorno limitado de seguridad de la aplicación de AIR (contenido instalado con la aplicación de AIR), debe añadir un prefijo al nombre de conexión con un superdominio que identifique la aplicación de AIR. La cadena de superdominio comienza con app# seguida del ID de aplicación y un punto (.), y el ID del editor (si está definido). Por ejemplo, el superdominio correcto para utilizar en el parámetro connectionName de una aplicación con ID de aplicación com.example.air.MyApp y sin ID de editor sería: "app#com.example.air.MyApp". Así, si el nombre de conexión base es “appConnection”, toda la cadena que se utilizará en el parámetro connectionName es: "app#com.example.air.MyApp:appConnection". Si la aplicación tiene ID de editor, este también debe incluirse en la cadena de superdominio: "app#com.example.air.MyApp.B146A943FBD637B68C334022D304CEA226D129B4.1".

Cuando se permite que otra aplicación de AIR se comunique con la aplicación a través de la conexión local, se debe llamar a allowDomain() del objeto LocalConnection, pasando el nombre del dominio de conexión local. Para una aplicación de AIR, este nombre de dominio se forma del ID de editor y de la aplicación de la misma manera que la cadena de conexión. Por ejemplo, si la aplicación de AIR de envío tiene un ID de aplicación com.example.air.FriendlyApp y un ID de editor 214649436BD677B62C33D02233043EA236D13934.1, entonces el la cadena de dominio que se usa para permitir la conexión de esta aplicación es: app##com.example.air.FriendlyApp.214649436BD677B62C33D02233043EA236D13934.1. (En AIR 1.5.3, no todas las aplicaciones de AIR tienen ID de editor.)