FrontPage
FlashでSocketやXMLSocketを使ってサーバにアクセスするには、ソケットポリシーファイルの設置が必須です。ソケットポリシーファイルはHTTPポリシーファイル(crossdomain.xml)とは別物です。
公式サイトも含め、いまいちまとまっていてかつ新しい情報が見つからなかったので、まとめてみました。以下の情報はFlash Player 6〜10に対応しています。
おすすめの設置方法 †
843番ポートに(ソケットマスターポリシーファイルとして)配置する方法です。
まずソケットポリシーファイル(仕様)を書きます。たとえばirc.gimite.netに置いてあるFlashから6667, 6668番ポートにアクセスできるようにするなら、こんな感じです。
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-access-from domain="irc.gimite.net" to-ports="6667,6668"/>
</cross-domain-policy>
どのホストからもアクセスできるようにしたければ、こんな感じです。
<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
<allow-access-from domain="*" to-ports="6667,6668"/>
</cross-domain-policy>
あとはサーバの843番ポートに何かの入力があったときに、このファイルの内容を返せばOKです。方法は何でもいいのですが、以下はinetdを使う例です。
- まずin.flashpolicyd.rbをダウンロード。(ちなみにAdobeのページで配布されているin.flashpolicyd.pyはバグっていて動きませんでした…。)
- 設定ファイルを編集。rubyコマンド、in.flashpolicyd.rb、ソケットポリシーファイル(socket-policy.xml)のパスは環境に合わせて書き換えてください。
# emacs /etc/services
以下の1行を追加:
flashpolicy 843/tcp
# emacs /etc/inetd.conf
以下の1行を追加:
flashpolicy stream tcp nowait root /usr/local/bin/ruby ruby /path/to/in.flashpolicyd.rb /path/to/socket-policy.xml
- inetdを再起動。
# /etc/rc.d/inetd restart (Free BSDの場合)
# /etc/init.d/openbsd-inetd restart (Debian Linuxの場合)
- ファイアウォールなどを設定している場合は、843番ポートを開けるのを忘れずに。
あとはActionScript?上で以下のように書けば、動くはずです。
Security.loadPolicyFile("xmlsocket://irc.gimite.net:843");
socket = new Socket("irc.gimite.net", 6667);
...
ソケットポリシーファイルまわりのFlash Playerの挙動 †
全バージョン共通 †
Flash Player 9.0.124.0以降 (Flash Player 10を含む) †
- ソケットポリシーファイルが必要なケース
- Socket、XMLSocketを使う場合は常にソケットポリシーファイルが必要。
- 接続先ポート
- まず843番ポート(ソケットマスターポリシーファイル)にアクセス。繋がらない or 3秒以内に返事がない場合は、次へ。
- Security.loadPolicyFile("xmlsocket://...");で指定されたポートがあれば、そこにアクセス。繋がらない or しばらく(20秒ぐらい?)返事がない場合は、次へ。URLがxmlsocket://...の場合のみ有効なので注意。Security.loadPolicyFile("http://...");で指定されたファイルはSocket、XMLSocketによる通信では無視される。
- Socketの接続先と同じポートにアクセス。適切なソケットポリシーファイルが受信できなければ、SecurityError?。
Flash Player 9.0.115.0以降 9.0.124.0以前 †
- ソケットポリシーファイルが必要なケース
- 1024未満のポートに接続するか、SWFファイルを提供しているホスト以外のホストに接続するときは、ソケットポリシーファイルが必要。
- 接続先ポート
Flash Player 7.0.19.0以降 9.0.115.0以前 †
- ソケットポリシーファイルが必要なケース
- Flash Player 9.0.115.0以降 9.0.124.0以前と同様。
- 接続先ポート
- Security.loadPolicyFile("xmlsocket://...");で指定されたポート、またはSecurity.loadPolicyFile("http://...");で指定されたURLがあれば、そこにアクセス。繋がらない or しばらく(20秒ぐらい?)返事がない場合は、次へ。
- Socketの接続先と同じポートにアクセス。適切なソケットポリシーファイルが受信できなければ、SecurityError?。
Flash Player 6以降 7.0.19.0以前 †
- ソケットポリシーファイルが必要なケース
- Flash Player 9.0.115.0以降 9.0.124.0以前と同様。
- 接続先ポート
- ソケットポリシーファイルには未対応。
- ソケットサーバへの接続は、ソケットサーバと同じホストのポート80上にあるHTTPサーバのデフォルトの場所に置かれているポリシーファイルによって承認されていた。
おすすめの設置方法をおすすめする理由 †
- 843番ポートに設置する理由
- Flash Player 9.0.124.0以降では必ず最初に843番ポートにアクセスします。それ以外のポートは、843番ポートを試して、失敗してから見に行くので、ちょっと時間がかかります。843番ポートが閉じている場合でも、手元の環境では1秒ぐらい余計にかかりました。
- 843番ポートに設置した場合でも Security.loadPolicyFile("xmlsocket://irc.gimite.net:843"); を書く理由
- 新しめのFlash Playerであれば、loadPolicyFile()なしでも一応動くのですが…
- Flash Player 9.0.115.0以前だとソケットマスターポリシーファイルに対応してないので、loadPolicyFile()がないと843番ポートを見に行ってくれません。
- 新しめのFlash Playerでも、loadPolicyFile()がない場合は、843番ポートから3秒返事がないと、843番ポートからの取得をあきらめてしまいます。これだとネットワークが遅かったりサーバが重かった場合にSecurityError?になる場合があります。loadPolicyFile()で指定したポートからの取得なら20秒ぐらいは待ってくれるようなので、この手のエラーを減らせます。
情報源 †
コメント †
間違いとか見つけたら教えてください。