Flash間データ通信:Socket

2009.10.2 金曜日

異なるPCで起動しているFlash間で通信を行いたい場合、TCPのソケットサーバーを間に立て、Socket通信を行うのがベストだと思います。FLASHはTCPといった遅い通信プロトコルを採用しているため、処理の重いString型を扱うXML Socket通信より、ByteArray型を扱うSocket通信を使った方が、若干スピードのメリットがあります。

話は逸れますが、Flashの扱えるTCPは信頼性>速度の通信プロトコルのため、データを確実に送ることはできますが、大容量のデータを送り続けた場合には数十秒のタイムラグが発生します。現在のFlashでは扱えないUDPは、信頼性<速度の通信プロトコルなので、いつかサポートしてほしいところです。プロトコルの詳しい情報はWikipediaの「TCP」と「UDP」などをご覧ください。

修正 2010.8.13
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(&amp;quot;localhost&amp;quot;, 3000);

			//clientB serverBに接続、リスナー登録
			clientB = new Socket();
			clientB.addEventListener(ProgressEvent.SOCKET_DATA, Recieve);
			clientB.connect(&amp;quot;localhost&amp;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|

trackback

http://tmdf.net/blog/20091002_flash_socket.html/trackback

comments(0)

POST NEW COMMENT

  • name:*
  • e-mail:*

    The content of this field is kept private and will not be shown publicly.
  • website:
  • comment:*

    Allowed HTML tags: <a> <em> <strong> <cite> <blockquote> <code>
    Lines and paragraphs break automatically.

Photo

PROFILE

森田 考陽 [Takaaki Morita]
Twitter: @tmdf
Other: mtdf.net

Designer / Programmer

RECENT POSTS

MONTHLY ARCHIVES