Comunicazione con altre istanze di Flash Player e Adobe AIR

Flash Player 9 e versioni successive, Adobe AIR 1.0 e versioni successive

La classe LocalConnection abilita la comunicazione tra le applicazioni Adobe® AIR®, oltre che tra il contenuto SWF eseguito nel browser. Potete anche utilizzare la classe LocalConnection per le comunicazioni tra un'applicazione AIR e il contenuto SWF in esecuzione nel browser. La classe LocalConnection consente di creare applicazioni estremamente versatili che possono condividere dati tra istanze Flash Player e AIR.

Informazioni sulla classe LocalConnection

La classe LocalConnection consente di sviluppare file SWF in grado di inviare istruzioni ad altri file SWF senza utilizzare il metodo fscommand() o JavaScript. Gli oggetti LocalConnection possono comunicare solo tra file SWF in esecuzione sullo stesso computer client, tuttavia possono essere eseguiti in applicazioni diverse. Ad esempio, un file SWF in esecuzione in un browser e un file SWF in esecuzione in un proiettore possono condividere le informazioni: il proiettore gestisce le informazioni locali, mentre il file SWF basato su browser si connette in remoto. Un proiettore è un file SWF salvato in un formato che può essere eseguito come applicazione autonoma, ovvero senza richiedere l'installazione di Flash Player essendo incorporato nell'eseguibile.

Gli oggetti LocalConnection possono essere utilizzati per la comunicazione tra file SWF che utilizzano versioni diverse di ActionScript:

  • Gli oggetti LocalConnection di ActionScript 3.0 sono in grado di comunicare con gli oggetti LocalConnection creati in ActionScript 1.0 e 2.0.

  • Gli oggetti LocalConnection di ActionScript 1.0 e 2.0 sono in grado di comunicare con gli oggetti LocalConnection creati in ActionScript 3.0.

Flash Player gestisce in modo automatico questa comunicazione tra oggetti LocalConnection di versioni diverse.

Il modo più semplice di usare un oggetto LocalConnection consiste nel consentire la comunicazione soltanto tra gli oggetti LocalConnection che si trovano nello stesso dominio o nella stessa applicazione AIR. In questo modo, non dovete preoccuparvi dei problemi legati alla sicurezza. Tuttavia, se dovete permettere la comunicazione tra domini diversi, esistono vari modi per implementare delle misure di sicurezza. Per ulteriori informazioni, vedete la discussione del parametro connectionName del metodo send() e le voci allowDomain() e domain nella classe LocalConnection elencata nella Guida di riferimento di Adobe ActionScript 3.0 per la piattaforma Adobe Flash .

È possibile utilizzare gli oggetti LocalConnection per inviare e ricevere dati in un solo file SWF; Adobe consiglia tuttavia di non utilizzare questo metodo. Utilizzate invece oggetti condivisi.

Sono disponibili tre modi per aggiungere metodi di callback agli oggetti LocalConnection:

  • Creare una sottoclasse della classe LocalConnection e aggiungere dei metodi.

  • Impostare la proprietà LocalConnection.client su un oggetto che implementi i metodi.

  • Creare una classe dinamica per estendere LocalConnection e associare in modo dinamico i metodi.

Il primo modo per aggiungere i metodi di callback consiste nell'estendere la classe LocalConnection. Definite i metodi all'interno della classe personalizzata anziché aggiungerli in modo dinamico all'istanza di LocalConnection. Questo approccio viene illustrato nel codice riportato di seguito:

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

Per creare una nuova istanza della classe CustomLocalConnection, potete utilizzare il codice riportato di seguito:

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

Il secondo modo per aggiungere i metodi di callback consiste nell'utilizzare la proprietà LocalConnection.client . In questa fase occorre creare una classe personalizzata e assegnare una nuova istanza alla proprietà client come illustrato nel codice riportato di seguito:

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

La proprietà LocalConnection.client indica i metodi di callback dell'oggetto da chiamare. Nel codice precedente la proprietà client è stata impostata su una nuova istanza della classe personalizzata CustomClient. Il valore predefinito per la proprietà client è l'istanza di LocalConnection corrente. Potete utilizzare la proprietà client se disponete di due gestori di dati con lo stesso set di metodi ma con un funzionamento diverso; ad esempio, in un'applicazione dove un pulsante in una finestra attiva/disattiva la vista in una seconda finestra.

Per creare la classe CustomClient, è possibile utilizzare il seguente codice:

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

Il terzo modo per aggiungere i metodi di callback, creando una classe dinamica e associando in modo dinamico i metodi, è molto simile all'utilizzo della classe LocalConnection nelle versioni precedenti di ActionScript, come illustrato nel codice riportato di seguito:

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

I metodi di callback possono essere aggiunti in modo dinamico a questa classe utilizzando il codice riportato di seguito:

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

Il precedente modo di aggiungere i metodi di callback non è consigliato, perché il codice non è molto portabile. Inoltre, l'utilizzo di questo metodo per la creazione delle connessioni locali potrebbe causare problemi a livello di prestazioni perché l'accesso alle proprietà dinamiche è significativamente più lento dell'accesso alle proprietà chiuse.

Proprietà isPerUser

La proprietà isPerUser è stata aggiunta a Flash Player (10.0.32) e AIR (1.5.2) per risolvere un conflitto che si verifica quando più utenti sono collegati a un computer Mac. In altri sistemi operativi, la proprietà viene ignorata poiché la connessione locale ha sempre avuto come area di validità i singoli utenti. La proprietà isPerUser deve essere impostata su true nel nuovo codice. Tuttavia, il valore predefinito è attualmente false per la compatibilità con le versioni precedenti. L'impostazione predefinita può essere modificata nelle versioni future dei runtime.

Invio di messaggi tra due applicazioni

La classe LocalConnection consente la comunicazione tra le diverse applicazioni AIR e tra queste e le applicazioni Adobe® Flash® Player (SWF) eseguite in un browser. Potete anche utilizzare la classe LocalConnection per le comunicazioni tra un'applicazione AIR e un'applicazione SWF in esecuzione in un browser.

Ad esempio, in una pagina Web potrebbero essere presenti più istanze di Flash Player oppure potrebbe essere presente un'istanza di Flash Player che recupera i dati da un'istanza di Flash Player in una finestra a comparsa.

Nel seguente codice viene definito un oggetto LocalConnection che funge da server e accetta le chiamate LocalConnection in entrata dalle altre applicazioni:
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"); 
            } 
        } 
    } 
}

Questo codice crea dapprima un oggetto LocalConnection denominato lc , quindi imposta la proprietà client su un oggetto, clientObject . Quando un'altra applicazione chiama un metodo in questa istanza di LocalConnection, il runtime esegue una ricerca di tale metodo nell'oggetto clientObject .

Se disponete già di una connessione con il nome specificato, viene generata un'eccezione ArgumentError, ad indicare che il tentativo di connessione non è riuscito perché l'oggetto era già connesso.

Ogni volta che un'istanza di Flash Player si connette a questo file SWF e tenta di chiamare un metodo qualsiasi per la connessione locale specificata, la richiesta viene inviata alla classe specificata dalla proprietà client , che è impostata sulla 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"); 
        } 
    } 
}

Per creare un server LocalConnection, chiamate il metodo LocalConnection.connect() e specificare un nome di connessione univoco. Se è già presente una connessione con il nome specificato, viene generato un errore ArgumentError, in cui è indicato che il tentativo di connessione non è riuscito in quanto l'oggetto è già connesso.

Il seguente snippet di codice illustra come creare una nuova connessione LocalConnection con il nome conn1 :
try 
{ 
    connection.connect("conn1"); 
} 
catch (error:ArgumentError) 
{ 
    trace("Error! Server already exists\n"); 
}
La connessione all'applicazione primaria da un'applicazione secondaria richiede dapprima la creazione di un nuovo oggetto LocalConnection nell'oggetto LocalConnection mittente, quindi l'esecuzione di una chiamata al metodo LocalConnection.send() con il nome della connessione e il nome del metodo da eseguire. Ad esempio, per inviare il metodo doQuit all'oggetto LocalConnection creato in precedenza, usate il codice riportato di seguito:
sendingConnection.send("conn1", "doQuit");

Questo codice stabilisce la connessione a un oggetto LocalConnection esistente con il nome di connessione conn1 e chiama il metodo doMessage() nell'applicazione remota. Se desiderate inviare parametri all'applicazione remota, specificate gli argomenti aggiuntivi dopo il nome del metodo nel metodo send() , come illustrato nel seguente snippet di codice:

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

Connessione al contenuto in domini diversi e ad applicazioni AIR

Per consentire la comunicazione soltanto da domini specifici, potete chiamare il metodo allowDomain() o allowInsecureDomain() della classe LocalConnection e passare un elenco di uno o più domini a cui è consentito accedere a questo oggetto LocalConnection., specificando uno o più nomi di domini autorizzati.

Nelle versioni precedenti di ActionScript, LocalConnection.allowDomain() e LocalConnection.allowInsecureDomain() erano metodi di callback che dovevano essere implementati dagli sviluppatori e che dovevano restituire un valore booleano. In ActionScript 3.0, LocalConnection.allowDomain() e LocalConnection.allowInsecureDomain() sono metodi incorporati che gli sviluppatori possono chiamare esattamente come Security.allowDomain() e Security.allowInsecureDomain() , passando uno o più nomi di domini a cui consentire l'accesso.

In Flash Player 8 sono state introdotte delle limitazioni di sicurezza per i file SWF locali. Un file SWF autorizzato ad accedere a Internet non può avere accesso anche al file system locale. Se specificate localhost , qualunque file SWF locale può accedere al file SWF. Se il metodo the LocalConnection.send() tenta di comunicare con un file SWF da una funzione di sicurezza sandbox a cui il codice chiamante non ha accesso, viene inviato un evento securityError ( SecurityErrorEvent.SECURITY_ERROR ). Per risolvere questo errore, potete specificare il dominio del chiamante nel metodo LocalConnection.allowDomain() del ricevente.

I valori speciali che è possibile passare ai metodi LocalConnection.allowDomain() e LocalConnection.allowInsecureDomain() sono due: * e localhost . Il valore asterisco (*) consente l'accesso da tutti i domini. La stringa localhost consente le chiamate all'applicazione dal contenuto installato localmente, ma esterno alla directory delle risorse dell'applicazione.

Se il metodo LocalConnection.send() tenta di comunicare con un'applicazione da una sandbox di sicurezza a cui il codice chiamante non ha accesso, viene inviato un evento securityError ( SecurityErrorEvent.SECURITY_ERROR ). Per risolvere questo errore, potete specificare il dominio del chiamante nel metodo LocalConnection.allowDomain() del ricevente.

Se implementate la comunicazione soltanto tra i contenuti nello stesso dominio, potete specificare un parametro connectionName che non inizi con un carattere di sottolineatura ( _ ) e che non specifichi un nome di dominio (ad esempio, myDomain:connectionName ). Utilizzate la stessa stringa nel comando LocalConnection.connect(connectionName) .

Se implementate la comunicazione tra i contenuti in domini diversi, potete specificare un parametro connectionName che inizi con un carattere di sottolineatura. L'uso del carattere di sottolineatura aumenta la portabilità tra domini del contenuto con l'oggetto LocalConnection ricevente. Di seguito sono illustrati i due casi possibili:

  • Se la stringa di connectionName non inizia con un carattere di sottolineatura (_), viene aggiunto un prefisso composto dal nome del superdominio e da un segno di due punti (ad esempio, "myDomain:connectionName" ). Benché ciò garantisca l'assenza di conflitti della connessione con le connessioni di altri domini che hanno lo stesso nome, tutti gli oggetti LocalConnection mittenti devono specificare questo superdominio (ad esempio, myDomain:connectionName ). Se spostate il file HTML o SWF con l'oggetto LocalConnection ricevente in un altro dominio, viene modificato il prefisso per rispecchiare il nuovo superdominio (ad esempio, anotherDomain:connectionName ). Tutti gli oggetti LocalConnection mittenti devono quindi essere modificati manualmente in modo da puntare al nuovo superdominio.

  • Se la stringa per connectionName inizia con un carattere di sottolineatura (ad esempio, _connectionName ), non viene aggiunto alcun prefisso alla stringa. Questo significa che gli oggetti LocalConnection riceventi e mittenti usano stringhe identiche per connectionName . Se l'oggetto ricevente utilizza LocalConnection.allowDomain() per specificare che vengano accettate le connessioni da qualunque dominio, potete spostare il file HTML o SWF con l'oggetto LocalConnection ricevente in un altro dominio senza alterare altri oggetti LocalConnection mittenti.

    L'uso di nomi con il carattere di sottolineatura in connectionName comporta comunque uno svantaggio, ovvero il rischio di conflitti quando due applicazioni, ad esempio, tentano di connettersi con lo stesso connectionName . Un secondo svantaggio riguarda invece la sicurezza. I nomi delle connessioni che usano la sintassi con il carattere di sottolineatura non identificano il dominio dell'applicazione in ascolto. Per queste ragioni, sono da preferire i nomi in cui è specificato il dominio.

Adobe AIR

Per comunicare con il contenuto in esecuzione nella sandbox di sicurezza dell'applicazione AIR (contenuto installato con l'applicazione AIR), è necessario far precedere al nome della connessione un superdominio che identifica l'applicazione AIR. La stringa del superdominio inizia con app# seguita dall'ID applicazione, da un carattere punto (.) e dall'ID editore (se definito). Ad esempio, il superdominio corretto da utilizzare nel parametro connectionName per un'applicazione con ID applicazione, com.example.air.MyApp e senza ID editore è: "app#com.example.air.MyApp" . Pertanto, se il nome connessione di base è “appConnection”, l'intera stringa da utilizzare nel parametro connectionName è: "app#com.example.air.MyApp:appConnection" . Se l'applicazione dispone di un ID editore, è necessario includere questo ID nella stringa del superdominio: "app#com.example.air.MyApp.B146A943FBD637B68C334022D304CEA226D129B4.1" .

Quando consentite a un'altra applicazione AIR di comunicare con la vostra applicazione tramite la connessione locale, dovete richiamare il metodo allowDomain() dell'oggetto LocalConnection specificando il nome del dominio della connessione locale. Nel caso di un'applicazione AIR, tale nome di dominio si forma a partire dagli ID dell'applicazione e dell'editore allo stesso modo con cui si forma la stringa di connessione. Ad esempio, se l'applicazione AIR mittente ha un ID applicazione com.example.air.FriendlyApp e un ID editore 214649436BD677B62C33D02233043EA236D13934.1 , la stringa di dominio che dovete usare per consentire a questa applicazione di connettersi è: app#com.example.air.FriendlyApp.214649436BD677B62C33D02233043EA236D13934.1 . (Analogamente a AIR 1.5.3, non tutte le applicazioni AIR dispongono di ID editore.)