Flash Player および AIR の他のインスタンスとの通信

Flash Player 9 以降、Adobe AIR 1.0 以降

LocalConnection クラスを使用すると、ブラウザーで実行される SWF コンテンツ間だけでなく、Adobe® AIR® アプリケーション間でも通信できます。また、LocalConnection クラスを使用して、AIR アプリケーションとブラウザーで実行される SWF コンテンツとの間で通信することもできます。 LocalConnection クラスを使用すれば、Flash Player および AIR の複数のインスタンス間でデータを共有し、用途の広いアプリケーションを作成できます。

LocalConnection クラスについて

LocalConnection クラスを使用すると、fscommand() メソッドや JavaScript を使用することなく他の SWF ファイルに命令を送信できる SWF ファイルを開発できます。LocalConnection オブジェクトでの通信相手は、同じクライアントコンピューター上で動作する SWF ファイルに限られますが、通信相手が同じアプリケーションで動作している必要はありません。例えば、ブラウザー上で動作している SWF ファイルとプロジェクターの SWF ファイルで情報を共有しつつ、プロジェクターがローカルの情報を管理し、ブラウザー上の SWF ファイルがリモート接続を実行するといった分担もできます。プロジェクターは、スタンドアローンアプリケーションとして実行可能な形式で保存される SWF ファイルです。つまり、実行可能ファイルの内部に埋め込まれているので、プロジェクトに Flash Player がインストールされている必要はありません。

LocalConnection オブジェクトは、異なるバージョンの ActionScript を使用した SWF 間の通信に使用できます。

  • ActionScript 1.0 または 2.0 の LocalConnection オブジェクトは、ActionScript 2.0 で作成された LocalConnection オブジェクトと通信できます。

  • ActionScript 1.0 または 2.0 の LocalConnection オブジェクトは、ActionScript 3.0 で作成された LocalConnection オブジェクトと通信できます。

Flash Player は、このバージョンが異なる LocalConnection オブジェクト間の通信を自動的に処理します。

LocalConnection オブジェクトの最も簡単な使用方法は、同じドメイン内または同じ AIR アプリケーション内の LocalConnection オブジェクト間の通信のみを許可することです。この場合、セキュリティに関する問題への対処は不要です。しかし、異なるドメイン間で通信を行う必要がある場合は、セキュリティ対策を実施する必要があります。いくつかの方法があります。詳しくは、 send() メソッドの connectionName パラメーターおよび LocalConnection クラスの allowDomain() domain のエントリに関する説明を参照してください。このクラスは、『 Adobe Flash Platform 用 ActionScript 3.0 リファレンスガイド 』のリストに含まれています。

LocalConnection オブジェクトを使用して 1 つの SWF ファイル内でデータを送受信することは可能ですが、お勧めしません。代わりに、共有オブジェクトを使用します。

LocalConnection オブジェクトにコールバックメソッドを追加するには、次の 3 つの方法があります。

  • LocalConnection クラスのサブクラスを作成してメソッドを追加する方法

  • LocalConnection.client プロパティを、メソッドを実装したオブジェクトに設定する方法

  • LocalConnection を拡張した動的なクラスを作成し、動的にメソッドを追加する方法

第 1 の方法では、LocalConnection クラスを拡張することでコールバックメソッドを追加します。 LocalConnection インスタンスに動的にメソッドを追加するのではなく、カスタムクラス内にメソッドを定義します。 この方法を使用する例を次のコードに示します。

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

CustomLocalConnection クラスの新しいインスタンスを作成する場合、次のコードを使用できます。

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

コールバックメソッドを追加する 2 つ目の方法は、 LocalConnection.client プロパティを使用する方法です。次のコードのように、カスタムクラスを作成し、そのクラスの新しいインスタンスを client プロパティに設定します。

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

LocalConnection.client プロパティは、呼び出されるオブジェクトのコールバックメソッドを指定します。このコードでは、 client プロパティに CustomClient というカスタムクラスの新しいインスタンスを設定しています。 client プロパティのデフォルト値は、現在の LocalConnection インスタンスです。例えば、あるウィンドウ内のボタンが別のウィンドウの表示を切り替えるアプリケーションのように、同じメソッドのセットが設定されていながら動作の異なる 2 つのデータハンドラーがある場合、 client プロパティを使用できます。

CustomClient クラスを作成するには、次のようなコードを使用します。

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

コールバックメソッドを追加する 3 つ目の方法は、ダイナミッククラスを作成してメソッドを動的に関連付ける方法です。この方法は次のコードが示すように、ActionScript の以前のバージョンで LocalConnection クラスを使用する方法と非常によく似ています。

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

コールバックメソッドは、次のコードを使用して、このクラスに動的に追加できます。

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

以前のコールバックメソッドの追加方法はコードの移植があまり簡単ではないため、お勧めしません。 また、この方法でローカル接続を作成すると、ダイナミックプロパティへのアクセスは sealed プロパティにアクセスするより大幅に時間を要するため、パフォーマンスの問題が起きるおそれがあります。

isPerUser プロパティ

isPerUser プロパティは、複数のユーザーが Mac コンピューターにログインしているときに発生する競合を解決するために、Flash Player (10.0.32)と AIR (1.5.2)に追加されました。他のオペレーティングシステムでは、ローカル接続は常に個別のユーザーが対象なので、このプロパティは無視されます。新規に作成するコードでは、 isPerUser プロパティを true に設定することが必要です。ただし、後方互換性のために、デフォルト値は現在 false です。このデフォルト値は、今後のバージョンのランタイムで変更される可能性があります。

2 つのアプリケーション間でのメッセージ送信

LocalConnection クラスを使用すると、異なる AIR アプリケーション間でも、ブラウザーで実行される異なる Adobe® Flash® Player(SWF)アプリケーション間でも通信できます。また、LocalConnection クラスを使用して、AIR アプリケーションとブラウザーで実行される SWF アプリケーションとの間で通信することもできます。

例えば、1 つの Web ページ上に複数の Flash Player インスタンスがある場合や、ポップアップウィンドウ内の Flash Player インスタンスから提供されるデータを別の Flash Player インスタンスで取得する場合などが考えられます。

次のコードでは、サーバーとして動作し、他のアプリケーションから受信する LocalConnection 呼び出しを受け付ける LocalConnection オブジェクトを定義します。
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"); 
            } 
        } 
    } 
}

このコードでは、まず、 lc という LocalConnection オブジェクトを作成し、 client プロパティを clientObject オブジェクトに設定します。この LocalConnection インスタンスのメソッドを別のアプリケーションが呼び出すと、ランタイムは clientObject オブジェクトでそのメソッドを探します。

指定した名前の接続が既に存在する場合は Argument Error 例外がスローされます。この例外は、オブジェクトが接続済みであるために接続の試行が失敗したことを示します。

Flash Player インスタンスがこの SWF ファイルに接続し、指定されたローカル接続に対してメソッドを呼び出そうとすると、そのたびに、 client プロパティで指定されたクラス(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"); 
        } 
    } 
}

LocalConnection サーバーを作成するには、 LocalConnection.connect() メソッドを呼び出して一意の名前を指定します。指定した名前の接続が既に存在する場合は ArgumentError エラーが発生します。このエラーは、オブジェクトが接続済みであるために接続の試行が失敗したことを示します。

次のコードでは、 conn1 という名前を指定して LocalConnection を作成する方法を示します。
try 
{ 
    connection.connect("conn1"); 
} 
catch (error:ArgumentError) 
{ 
    trace("Error! Server already exists\n"); 
}
第 1 のアプリケーションに第 2 のアプリケーションから接続するには、まず、送信側 LocalConnection オブジェクト内で LocalConnection オブジェクトを作成し、次に、接続名と実行するメソッドの名前を指定して LocalConnection.send() メソッドを呼び出す必要があります。例えば、前述の例で作成した LocalConnection オブジェクトに doQuit メソッドを送信するには、次のコードを使用します。
sendingConnection.send("conn1", "doQuit");

このコードでは、既存の LocalConnection オブジェクトに接続名 conn1 で接続し、リモートアプリケーションの doMessage() メソッドを呼び出しています。リモートアプリケーションにパラメーターを送信する場合は、次のコードに示すように、 send() メソッドに対するメソッド名の指定の後に追加パラメーターを指定します。

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

異なるドメインのコンテンツおよび AIR アプリケーションへの接続

特定のドメインからの通信のみ許可するには、LocalConnection クラスの allowDomain() メソッドまたは allowInsecureDomain() メソッドを呼び出し、この LocalConnection オブジェクトへのアクセスを許可するドメインのリストを渡し、許可するドメインの 1 つ以上の名前を渡します。

ActionScript の以前のバージョンでは、開発者が LocalConnection.allowDomain() および LocalConnection.allowInsecureDomain() をコールバックメソッドとして実装する必要があり、また、いずれも戻り値として Boolean 値を返すようにする必要がありました。ActionScript 3.0 では、 LocalConnection.allowDomain() および LocalConnection.allowInsecureDomain() は両方ともビルトインメソッドとなりました。開発者はアクセスを許可するドメイン名を渡して、これらのメソッドを Security.allowDomain() Security.allowInsecureDomain() と同様に呼び出すだけで済みます。

Flash Player 8 から、ローカル SWF ファイルに関するセキュリティ制限が導入されました。 これにより、インターネットへのアクセスを許可された SWF ファイルは、ローカルファイルシステムにはアクセスできません。 localhost を指定すると、どのローカル SWF ファイルもこの SWF ファイルにアクセスできます。セキュリティ Sandbox 内から、呼び出し元コードがアクセスを認められていない SWF ファイルに対して LocalConnection.send() メソッドで接続しようとすると、 securityError event( SecurityErrorEvent.SECURITY_ERROR )が送出されます。このエラーを回避するには、受信側の LocalConnection.allowDomain() メソッドで、呼び出し元のドメインを指定してください。

LocalConnection.allowDomain() メソッドおよび LocalConnection.allowInsecureDomain() メソッドに渡すことができる特別な値として、 * localhost の 2 つがあります。アスタリスク値 (*) は、すべてのドメインにアクセスを許可することを示します。 localhost というストリングは、ローカル(ただし、アプリケーションリソースディレクトリ外)にインストールされているコンテンツから該当のアプリケーションへの呼び出しを許可することを示します。

LocalConnection.send() メソッドで、呼び出し元コードでのアクセスが認められていないアプリケーションにセキュリティサンドボックスから通信しようとすると、 securityError イベント( SecurityErrorEvent.SECURITY_ERROR )が送出されます。このエラーを回避するには、受信側の LocalConnection.allowDomain() メソッドで、呼び出し元のドメインを指定してください。

同じドメイン内のコンテンツ間のみで通信を行う場合は、 connectionName パラメーターに対して、先頭がアンダースコア( _ )以外で、かつドメイン名を含まない名前を指定します(例: myDomain:connectionName )。また、それと同じストリングを LocalConnection.connect(connectionName) コマンドでも使用します。

異なるドメインにあるコンテンツ間での通信を実装する場合は、 connectionName パラメーターに対して、アンダースコアで始まる名前を指定します。このアンダースコアを付けると、受信側 LocalConnection オブジェクトを含むコンテンツのドメイン間におけるポータビリティが高まります。考えられる 2 つの状況を次に示します。

  • connectionName のストリングがアンダースコア(_)で始まっていない場合、 myDomain:connectionName のように、スーパードメイン名とコロンの接頭辞がランタイムによって追加されます。この処理には他のドメインにある同じ名前の接続との競合を回避する意味がありますが、その代わり、このスーパードメインをすべての送信側 LocalConnection オブジェクトで指定する必要があります(例: myDomain:connectionName )。受信側 LocalConnection オブジェクトを含んだ HTML ファイルまたは SWF ファイルを別のドメインに移動すると、ランタイムによって追加される接頭辞は、スーパードメインの変更を反映して変化します(例: anotherDomain:connectionName )。したがって、新しいスーパードメインを参照するようにすべての送信側 LocalConnection オブジェクトを手動で編集する必要が生じます。

  • connectionName のストリングが、 _connectionName のようにアンダースコアで始まっている場合、ストリングに接頭辞は追加されません。つまり、受信側と送信側の LocalConnection オブジェクトは、 connectionName にまったく同じストリングを使用します。すべてのドメインからの接続を受け付けることを受信側オブジェクトが LocalConnection.allowDomain() によって指定していれば、受信側 LocalConnection オブジェクトを含んだ HTML ファイルまたは SWF ファイルを別のドメインに移動した場合でも、送信側 LocalConnection オブジェクトに変更を加える必要はありません。

    connectionName でアンダースコア付きの名前を使用する場合の欠点の 1 つは、2 つのアプリケーションの両方が同じ connectionName を使用して接続しようとする場合など、競合の可能性があることです。もう 1 つの欠点は、セキュリティ関連です。アンダースコアシンタックスを使用する接続名では、リッスンしているアプリケーションのドメインは識別されません。これらの理由から、ドメイン修飾名の使用が推奨されます。

Adobe AIR

AIR アプリケーションセキュリティサンドボックス内で実行するコンテンツ(AIR アプリケーションでインストールされたコンテンツ)と通信するには、接続名に AIR アプリケーションを識別するスーパードメイン名を接頭辞として付加する必要があります。スーパードメインのストリングは、 app# で始まり、アプリケーション ID、ドット(.)文字、発行者 ID (定義されている場合)と続きます。例えば、アプリケーション ID が com.example.air.MyApp で、発行者 ID はないアプリケーションに対して、 connectionName パラメーターで使用する適切なスーパードメインは、「 app#com.example.air.MyApp 」です。このようにして、接続名のベース部分が appConnection の場合、 connectionName パラメーターで使用されるストリング全体は、「 app#com.example.air.MyApp:appConnection 」となります。アプリケーションに発行者 ID がある場合は、その ID もスーパードメインのストリングに組み込んで、「 app#com.example.air.MyApp.B146A943FBD637B68C334022D304CEA226D129B4.1 」などとする必要があります。

ローカル接続を通じて別の AIR アプリケーションからユーザーのアプリケーションに通信できるようにする場合は、LocalConnection オブジェクトの allowDomain() を呼び出し、ローカル接続のドメイン名を渡す必要があります。AIR アプリケーションでは、このドメイン名は接続ストリングと同じ要領でアプリケーション ID と発行者 ID により構成されます。例えば、送信側 AIR アプリケーションのアプリケーション ID が com.example.air.FriendlyApp で、発行者 ID が 214649436BD677B62C33D02233043EA236D13934.1 である場合、このアプリケーションから接続するときに使用するドメインストリングは「 app#com.example.air.FriendlyApp.214649436BD677B62C33D02233043EA236D13934.1 」になります。(AIR 1.5.3 の時点では、すべての AIR アプリケーションに発行者 ID が付いているわけではありません)。