LocalConnection wird in Flash verwendet damit mehrere Flashdateien mit einander kommunizieren können.
Dieser Artikel soll die Grundlagen aufzeigen, jedoch ist das normale LocalConnection sehr fehleranfällig wenn die Flashdateien von verschiedenen Server oder
einem Lastenverteiler geladen werden.
Hier tretten teilweise Verzögerungen in Millisekunden Bereich auf, die aber ausreichen damit die asLocalConnection im Internet Explorer oder anderen Browsern nicht mehr richtig funktioniert.
Aus diesem Grund wurde die Erweiterung asLocalConnect entwickelt, die helfen soll genau diese Fehler zu umgehen und andere nützliche Features wurden hinzu gefügt.
Mehr zu asLocalConnect finden Sie unter Projekte - asLocalConnect.
Inhalt
LocalConnection mit ActionScript 2
LocalConnection mit ActionScript 3 (CS3)
LocalConnection sind relative einfach zu verwenden, zuerst wird ein Empfänger und ein Sender definiert.
Anschließend teilt man dem Empfänger mit wie er auf bestimmte Anfragen reagieren soll und kann dann eine LocalConnection zwischen dem Sender
und dem Empfänger aufbauen.
Sobald der Empfänger eine Anfrage vom Sender erhält, versucht er die dazu festgelegt Action auszuführen.
In der Praxis wird LocalConnection verwendet um Animationen/Flashdateien zu synchronisieren oder aber um einfach und schnell
Daten zwischen mehreren Flashdateien auszutauschen.
Der große Vorteil von LocalConnection ist das diese ohne JavaScript oder FSCommands auskommt und somit sogar zwischen 2 verschiedenen Browser Daten austauschen kann.
Zum Beispiel: Flash A im Internet Explorer und Flash B im Firefox und Flash C im Flashplayer .
Jedoch sollte dies nie so live verwendet werden, es ist jedoch eine gute Möglichkeit die LocalConnection zu testen.
Hier kann man die Flash A im Flash Editor ansehen und erhält alle trace() Ausgaben und Flash B wird z.B: im Flashplayer oder im Browser aufgerufen.
Da LocalConnection im engeren Sinne nur Daten austauscht, ist dies sogar zwischen verschiedenen Flashversionen und ActionScript Versionen möglich.
Somit ist es nicht nötig, das beide Flashversionen in der selben Version vorliegen oder in der selben ActionScript Code Version programmiert sind.
Hier wird ein einfaches Beispiel gezeigt wird eine LocalConnection in ActionScript 2 aussehen kann.
Empfäger definieren
var empfaenger_lc:LocalConnection = new LocalConnection();
empfaenger_lc.connect("lc_empfaenger");
empfaenger_lc.funktion_test = function(param:String):Void { txt.text = param; };
Die erste Zeile erstellt ein LocalConnection Object mit den Namen "empfaenger_lc", in der zweiten Zeile wird eingestellt das diese LocalConnection den Namen "lc_empfaenger" hat.
Die letzte Zeile legt fest das "funktion_test" zu der LocalConenction mit den Namen "lc_empfaenger" gehört und hier der übergebene Text in die Textarea mit den Namen "txt" geschrieben werden soll.
Sender definieren
Das nachfolgende Beispiel sendet an dem Empfänger aus dem vorherigen Beispiel ein einfaches "Hello World".
var sender_lc:LocalConnection = new LocalConnection();
sender_lc.send("lc_empfaenger", "funktion_test", "Hello World");
Die erste Zeile legt wieder ein LocalConnection Object mit den Namen "sender_lc" fest.
Da hier nur Daten gesendet werden, muss diese LocalConnection keinen Namen besitzen auf den Sie reagieren soll.
Die letzte Zeile sendet "Hello World" an die LocalConnection mit den Namen "lc_empfaenger" and die Funktion "funktion_test".
Kurzübersicht
Übersicht über Ereignisse
| Event | Beschreibung | ||
|---|---|---|---|
empfaenger_lc.allowDomain = function ([sendingDomain:String]) {} | Wird aufgerufen, wenn empfaenger_lc eine Anforderung zum Aufrufen einer Methode von einem sendenden LocalConnection-Objekt erhält. | ||
empfaenger_lc.allowInsecureDomain = function([sendingDomain:String]) {} | Wird immer dann aufgerufen, wenn empfaenger_lc, das sich in einer SWF-Datei auf einer Domäne mit sicherem Protokoll (HTTPS) befindet, eine Anforderung zum Aufrufen einer Methode von einem sendenden LocalConnection-Objekt erhält, das sich in einer SWF-Datei befindet, die wiederum in einem nicht sicheren Protokoll gehostet wird. | ||
sender_lc.onStatus = function(infoObject:Object) {} | Wird aufgerufen, wenn ein sendendes LocalConnection-Objekt versucht, einen Befehl an ein empfangendes LocalConnection-Objekt zu senden. | ||
Übersicht über Konstruktoren
| Syntax | Beschreibung | ||
|---|---|---|---|
empfaenger_lc = new LocalConnection() | Erstellt ein LocalConnection-Objekt. | ||
Übersicht über Methoden
| Syntax | Beschreibung | ||
|---|---|---|---|
empfaenger_lc.close() : Void | Schließt das LocalConnection-Objekt (bricht die Verbindung ab). | ||
empfaenger_lc.connect(connectionName:String) : Boolean | Bereitet ein LocalConnection-Objekt auf den Empfang von Befehlen eines LocalConnection.send()-Befehls vor (das so genannte sendende LocalConnection-Objekt). | ||
empfaenger_lc.domain() : String | Gibt einen String zurück, der die Domäne des Pfads der aktuellen SWF-Datei angibt. | ||
sender_lc.send(connectionName:String, methodName:String, [args:Object]) : Boolean | Ruft die Methode method für eine mit dem Befehl LocalConnection.connect( connectionName ) geöffnete Verbindung auf (das so genannte empfangende LocalConnection-Objekt). | ||
In ActionScript 3, sieht dies oben genannte Beispiel nur ein wenig anders aus, die Funktion wird nicht mehr der LocalConnection zugeordnet, sonder es kann jede beliebige Funktion aufgerufen werden.
Dies ermöglicht es ohne viel zusätzlichen Aufwand über LocalConnection eine Flashdatei von auserhalb zu steuern.
Jedoch sollte hier genau darauf geachtet werden, in wie fern man dies zulässt, da man so auch aus versehen was verstellen kann.
Empfänger definieren
import flash.net.LocalConnection;
var empfaenger_lc:LocalConnection = new LocalConnection();
empfaenger_lc.connect("lc_empfaenger");
function funktion_test(param:String):void {
txt.text = param;
};
empfaenger_lc.client = this;
Hier wird mit empfaenger_lc.client = this; festgelegt, das alle Funktionen innerhalb von this über LocalConnection ausgeführt werden dürfen.
Sender definieren
Der Sender unterscheidet sich bis auf die "imports" nicht von Action Script 2, aus diesem Grund kann wie gesagt auch ein Localconenction zwischen ActionScript 2 und ActionScript 3 statt finden.
Aber es gibt einige Features die in ActionScript2 noch nicht existiert haben, in dem Fall wäre wieder "asLocalConnect" interessant.
import flash.net.LocalConnection;
var sender_lc:LocalConnection = new LocalConnection();
sender_lc.send("lc_empfaenger", "funktion_test", "Hello World");
Die Zeile import flash.net.LocalConnection; wird im Flash 9 Editor nicht unbedingt benötigt jedoch im jeden Fall in ausgelagerten ActionScript Dateien.
Diese Zeile schadet aber auch nichts und somit sollte man sich angewöhnen diese auch hier hinzu zufügen, damit hat man später weniger Arbeit wenn man das ActionScript doch mal in einer Datei auslagern will oder muss.
Kurzübersicht
Übersicht über Ereignise
| Event | Beschreibung | ||
|---|---|---|---|
asyncError | Wird aufgerufen, wenn die LocalConnection Verbindung asynchron ist. | ||
securityError | Wird immer dann aufgerufen, wenn LocalConnect.send() versucht Daten zu einer anderen Domain zu senden, die nicht innerhalb der Sicherheitseinstellungen definiert ist. | ||
status | Wird aufgerufen, wenn LocalConnection-Objekt seinen Status mitteilt. | ||
Übersicht über Eigenschaften
| Eigenschaft | Beschreibung | ||
|---|---|---|---|
client : Object | Kennzeichnet das Objekt von welchen Callback Methoden aufgerufen werden. | ||
domain : String | Einen String, der die Domäne des Pfads der aktuellen SWF-Datei angibt. | ||
Übersicht über Methoden
| Syntax | Beschreibung | ||
|---|---|---|---|
empfaenger_lc = new LocalConnection() | Erstellt ein LocalConnection-Objekt. | ||
empfaenger_lc.allowDomain(... domains) : void | Legt eine oder mehrere Domains fest, welche LocalConnection Anfragen zu dieser LocalConnection-Instanc senden können. | ||
empfaenger_lc.allowInsecureDomain(... domains) : void | Legt eine oder mehrere Domains fest, welche LocalConnection Anfragen zu diesem LocalConnection-Object senden können. | ||
empfaenger_lc.close() : Void | Schließt das LocalConnection-Objekt (bricht die Verbindung ab). | ||
empfaenger_lc.connect(connectionName:String) : void | Bereitet ein LocalConnection-Objekt auf den Empfang von Befehlen eines LocalConnection.send()-Befehls vor (das so genannte sendende LocalConnection-Objekt). | ||
sender_lc.send(connectionName:String, methodName:String, ... arguments) : void | Ruft die Methode method für eine mit dem Befehl LocalConnection.connect( connectionName ) geöffnete Verbindung auf (das so genannte empfangende LocalConnection-Objekt). | ||
Leider gibt es eine Irrglauben bei LocalConnection, das man hiermit Flashdateien synchronisieren kann, dies ist leider falsch.
Das Hauptproblem liegt daran, das LocalConnection teilweise verzögert reagiert und von der Framerate abhängig ist.
Mit höhere Framerate entsteht aber auch ein höhere Prozessorverbrauch und somit auch ein gewisser LAG.
Ein Artikel über FrameRate in Flash ist unter Flash -> Erweiterte Grundlagen -> FrateRate zu finden.
Es ist also nicht möglich zwei Flashdatein zeitgleich über LocalConnection zu steuern. Es gibt einige Tricks, wo diese Verzögerungen vermieden werden, jedoch keine 100% Lösung.
Die einzige Möglichkeit um zwei Flashdateien wirklich zeitgleich zu starten ist mit Hilfe von Javascript. Hier ist es möglich die 2 Flashdateien zu starten, zu prüfen ob beide vollständige geladen sind und anschließen werden dann beide zeitgleich gestartet.
Es sollte auch klar sein, das dieses Synchronisieren immer mit Programmierung zusammen hängt, entweder durch ActionScript oder durch JavaScript.
Somit hat ein reiner Grafiker meist Probleme damit, dies zu verstehen oder eine geeignete Lösung zu entwickeln.
Es gibt eine Reihe von bekannten Probleme mit LocalConnection vor allem im Zusammenhang mit dem Internet Explorer.
Verzögerungen von LocalConnection
Das Hauptproblem beim Internet Explorer besteht darin, das der Flashplayer nicht direkt sonder über ActiveX geladen wird.
Wenn man nun den Eolas Patch umgehen will, muss der Content über JavaScript dynamisch in die Seite geschrieben werden, was auch wieder zu einer Verzögerung führt.
Internet Explorer -> Webseite -> JavaScript -> ActiveX -> Flashplayer
Diese Verzögerungen sind zwar minimal aber reichen im normal Fall aus, dass die LocalConnection verzögert oder nicht reagiert.
Durch die Umstellung des wmode auf window, bekommt man einen Geschwindigkeitsvorteil. In den meisten Fällen reicht dies aus, damit die Verzögerung verringert wird.
Jedoch ist der wmode window ein spezieller Player-Modus, es ist hier nicht möglich andere Element über der Flashdatei anzeigen zu lassen oder alle Style-Attribute zu verwenden.
<
Mehrere gleichzeitige Aufrufe
Ein anderes Problem besteht darin wenn Flashdatein mit LocalConnection mehrmals geladen werden.
Nehmen wir man an, wir haben eine LocalConnection auf einer Webseite und wir bekommen zufälligerweise die Flashdateien ein zweites mal angezeigt weil wir zwei Browserfenster oder Browsertabs offen haben.
Es kann auch sein das die Flashdatei auch noch auf anderen Webseiten verwendet wird, es würde folgendes passieren:
1. BrowserTAB / Fenster
- Flash A (1. LocalConnection Empfänger)
- Flash B (2. LocalConnection Sender)
2. BrowserTAB / Fenster
- Flash A (3. LocalConnection Empfänger)
- Flash B (4. LocalConnection Sender)
Es darf immer nur einen Empfänger (Empfängername) in LocalConnection geben, alle anderen Empfänger werden einfach nicht zugelassen.
So sendet die Flash B aus dem ersten und zweiten BrowserTAB / Fenster, immer nur Daten an die Flash A aus dem ersten Fenster.
Die Flash A aus dem zweiten Fenster wird nie Daten erhalten, auch nicht wenn der erste BrowserTAB / Fenster geschlossen wird.
Hinweis: LocalConnection funktioniert auch zwischen verschiedenen Browser und sogar zwischen Browser und Desktop.
Dieses Problem lässt sich relativ einfach einschränken, man kann die AllowDomain so setzten das nur eine Domain gültig ist.
Hier geht es aber um AllowDomain innerhalb von ActionScript nicht um den Tag Parameter.
Eine weitere Möglichkeit wäre, an die Flashdatei über FlashVars eine ID mit zu übergeben, welche dann an den LocalConnection Namen angehängt wird.
Diese ID müsste sich für jeden Aufruf ändern und muss natürlich für Flash A und Flash B auf der gleichen Seite den die Gleiche sein.
Beispiel:
1. BrowserTAB / Fenster
- Flash A (ID 123)
- Flash B (ID 123)
2. BrowserTAB / Fenster
- Flash A (ID 321)
- Flash B (ID 321)
Hier würden die LocalConnection also nur innerhalb des eigenen Fenster Daten senden und empfangen und diese nicht an einen anderen BrowserTAB / Browserfenster oder Flashplayer senden.
Beispiel für eindeutige (unique) LocalConnection Namen
Das nachfolgende Beispiel soll auf einfache Art und Weise zeigen wie einfach es ist einen entsprechenden eindeutigen LocalConnection Namen zu verwenden.
Dies führt dazu das sich die selben Flashdateien die in unterschiedlichen Browser oder in unterschiedlichen TABs aufgerufen werden sich nicht gegenseitig stören.
<object type="application/x-shockwave-flash" data="flashfileA.swf" width="200" height="200" name="flashfileA" ID="flashfileA">
<param name="movie" value="flashfileA.swf">
<param name="FlashVars" value="rnd=[Zufallszahl]">
<param name="AllowScriptAccess" value="always">
</object>
...
<object type="application/x-shockwave-flash" data="flashfileB.swf" width="200" height="200" name="flashfileB" ID="flashfileB">
<param name="movie" value="flashfileB.swf">
<param name="FlashVars" value="rnd=[Zufallszahl]">
<param name="AllowScriptAccess" value="always">
</object>
Es ist wichtig das bei jedem Aufruf beide Flashdateien die selbe Zufallszahl erhalten.
Die Zufallszahl kann entweder Serverseitig (Webserver, CMS System) mit Perl, PHP oder ASP erzeugt werden oder Clientseitig (Browser) mit JavaScript.
Nachdem die Zufallszahl für beide Flashdateien als Flashvars übergeben worden ist, kann diese einfach in Flash ausgelesen werden und für die Verbindungen verwendet werden.
Dadurch das pro Aufruf immer die selbe Zufallszahl übergeben wird, können die Flashdateien für diesen einzelnen Aufruf miteinander kommuniziere, jedoch nicht mit Flashdateien mit anderen Zufallszahlen.
Dies verhindert also das sich die LocalConnection von mehreren Flashdateien in die quere kommen können.
var lc:LocalConnection = new LocalConnection();
button.onRelease = function() {
if (txt.text) {
lc.send("FlashB" + _level0.rnd, "setText", txt.text);
}
};
Da für einen reinen Sender kein eigener LocalConnection Name für ActionScript2 nötig ist, wird hier die übergebene Zufallszahl nur an den Empfängernamen hinzugefügt.
var lc:LocalConnection = new LocalConnection();
lc.connect("FlashB" + _level0.rnd);
lc.allowDomain = function(sendingDomain:String):Boolean {
return (this.domain() == sendingDomain);
};
lc.setText = function(text:String):Void {
if (text) {
txt.text = text;
}
};
Der Empfänger hängt an seinen LocalConnection Name auch die entsprechende Zufallszahl mit an, so können nun beide Flashdateien miteinander kommunizieren und kommen anderen LocalConnections nicht in die quere.
Es ist auch möglich dies innerhalb der Flashdatei vorzunehmen, man kann also prüfen ob der LocalConnection Namen bereits verwendet wird und falls ja wird eine andere Zufallszahl verwendet.
Wer sich nicht die Mühe machen möchte diese zu programmieren oder sich unsicher ist wie dies aussehen könnten, kann die Erweiterung asLocalConnect verwenden, die viele diese Aufgaben automatisch erledigt.
Flashdatei verstecken (display: none / visiblity: hidden)
Wenn man über JavaScript / CSS mit style="display: none;" oder style="visibility: hidden;" eine Flashdatei versteckt, so reagiert diese leider in jedem Browser verschieden.
Auch beim wieder anzeigen der Flashdatei über JavaScript / CSS mit style="display: block;" oder style="visibility: visible;" verhält sich jeder Browser anders.
Firefox / Mozilla Browser
Dieser beendet beim verstecken die LocalConnection und entlädt die Flashdatei, so das diese also nicht mehr mit LocalConnection ansprechbar ist oder auch selbst keine Daten mehr sendet.
Sollte die Flashdatei wieder angezeigt werden, so wird diese wieder aus dem Speicher geladen und starte von vorne.
Da dies alle Flashdateien in Firefox betrifft, wird hier die LocalConnection wieder erfolgreich aufgebaut.
Internet Explorer 6 / 7 / 8
Der Internet Explorer verhält sich hier wieder komplett anders, wenn eine Flashdatei versteckt wird, bleibt die LocalConnection bestehen, auch wird die Flashdatei weiter abgespielt.
Sollte die Flashdatei also beim Frame 10 ausgeblendet worden sein und wird wieder angezeigt so kann es sein das diese Ihr Ende auf Frame 300 schon erreicht hat.
Der Internet Explorer startet also die Flashdatei nicht neu, wenn diese wieder angezeigt wird.
Dieses Verhalten erzeugt einige Probleme vor allem mit der LocalConnection, da diese teilweise doppelte definiert werden kann.
Die Flashdatei läuft im Hintergrund weiter, jedoch werden nicht alle Events und Actionen ausgeführt, somit kann es sein das die LocalConnection verloren geht.
Damit die LocalConnection einwandfrei funktioniert, muss die Flashdatei nach einem verstecken und anzeigen wieder von vorne gestartet werden.
Dies erreicht man relativ einfach über JavaScript, da der Internet Explorer der einzige mir bekannte Browser ist, der ein solches Verhalten hat ist hier kein Crossbrowser Script nötig.
Anbei ein einfaches Beispiel, welches Daten von einer Flashdatei zu einer anderen Flashdatei schickt.
Flash A - Sender Flash
Der unter stehende ActionScript Code sendet bei einen Klick auf den Button "Text an Flash B" schicken, den eingegeben Text an FlashB und ruft dort die Funktion "setText" auf.
var lc:LocalConnection = new LocalConnection();
button.onRelease = function() {
if (txt.text) {
lc.send("FlashB", "setText", txt.text);
}
};
Flash B - Empfänger Flash
Im unter stehenden Actionscript wird eine "allowDomain" Funktion definiert, diese gibt einfach den Wert "true" zurück,
wenn die Anfrage von der selben Domain kommt wie die Empfänger Datei liegt.
var lc:LocalConnection = new LocalConnection();
lc.connect("FlashB");
lc.allowDomain = function(sendingDomain:String):Boolean {
return (this.domain() == sendingDomain);
};
lc.setText = function(text:String):Void {
if (text) {
txt.text = text;
}
};
