Flash間データ通信:Socket
2009.10.2 金曜日
異なるPCで起動しているFlash間で通信を行いたい場合、TCPのソケットサーバーを間に立て、Socket通信を行うのがベストだと思います。FLASHはTCPといった遅い通信プロトコルを採用しているため、処理の重いString型を扱うXML Socket通信より、ByteArray型を扱うSocket通信を使った方が、若干スピードのメリットがあります。
話は逸れますが、Flashの扱えるTCPは信頼性>速度の通信プロトコルのため、データを確実に送ることはできますが、大容量のデータを送り続けた場合には数十秒のタイムラグが発生します。現在のFlashでは扱えないUDPは、信頼性<速度の通信プロトコルなので、いつかサポートしてほしいところです。プロトコルの詳しい情報はWikipediaの「TCP」と「UDP」などをご覧ください。
AIR2.0からUDPのサポート、TCPサーバー(以前はクライアントだけ)にもなれます。
Flashの間に立てるソケットサーバーですが、フリーウェアでは「Socket Debugger (Free)」があります。このソフトウェアはバッファサイズが99,999Byteが限度のようなので、大きいデータのリアルタイムなやりとりには向きませんが、ちょっとしたテスト環境の構築には便利です。
また、単純なTCPサーバーならProcessingでも作れます。下記コードでは「Flash clientA」からポート3000を通して「Processing serverA」にデータを送り、受信したデータを「Processing serverB」からポート3001経由で「Flash clientB」に戻しています。動作検証用のサンプルなので、同じPC内(localhost)にサーバーとクライアントの全てを起動させていますし、接続確認や細かいエラー処理などは省いています。Processing → FLASHの順に起動し、FLASHの画面をクリックするとデータの送受信を行います。
//Server.pde
import processing.net.*;
//サーバー変数
Server serverA;
Server serverB;
//初期設定
void setup() {
//サーバーの作成
serverA = new Server(this, 3000);
serverB = new Server(this, 3001);
}
//常時実行
void draw() {
//serverAに接続しているクライアントを取得
Client client = serverA.available();
//クライアントがいた場合
if (client != null) {
//データを取得
String data = client.readString();
//データがある場合
if (data != null) {
//serverBに書き込み
serverB.write(data);
}
}
}
//Client.as
package {
import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.events.ProgressEvent;
import flash.net.Socket;
public class Client extends MovieClip {
//クライアント変数
private var clientA:Socket;
private var clientB:Socket;
//初期設定
public function Client():void {
//リスナー登録
stage.addEventListener(MouseEvent.CLICK, Send);
//clientA serverAに接続
clientA = new Socket();
clientA.connect(&quot;localhost&quot;, 3000);
//clientB serverBに接続、リスナー登録
clientB = new Socket();
clientB.addEventListener(ProgressEvent.SOCKET_DATA, Recieve);
clientB.connect(&quot;localhost&quot;, 3001);
}
//データ送信
private function Send(e:MouseEvent):void {
//データを書き込み
clientA.writeUTFBytes(String(Math.random()));
//serverAに送信
clientA.flush();
}
//データ受信
private function Recieve(e:ProgressEvent):void {
//受信した文字データを出力
trace(clientB.readUTFBytes(clientB.bytesAvailable));
}
}
}
Posted by tmdf|ActionScript Network Processing