kkAyatakaのメモ帳。

誰かの役に立つかもしれない備忘録。

AIR.Socketでメッセージをやりとりする

TCP/IPで相互にメッセージを送受信する。
ここでは簡単に、ボタンを押したら"メッセージ"という文字列を送信することにする。

ServerSocket側

まずは通信用のSocketを確保。

private function serverSocket_connectHandler(event:ServerSocketConnectEvent):void
{
	trace( "connect !" );
	socket = event.socket;
	socket.addEventListener(ProgressEvent.SOCKET_DATA, socket_socketDataHandler);
}

ServerSocketのConnectイベントで、つながったSocketオブジェクトが取得できる。
なので、Connectイベント内でSocketを確保し、メッセージ受信用のイベントを登録する。


受信イベントでメッセージが見えるようにtrace。

private function socket_socketDataHandler(event:ProgressEvent):void
{
	var sokcet:Socket = event.target as Socket;
	trace( "socket socket data:" + socket.readUTF() );
}

EventオブジェクトからSocketを取得。
文字列通信なので、readUTFでSocketから読み出す。


んで、書き込み。
書き込みはボタン押下時に行う。

private function sendBtn_clickLogic():void
{
	if( socket ) {
		socket.writeUTF( "メッセージ" );
		socket.flush();
	}
}

Connect時に確保したSocketにwriteUTFで文字列を書き込む。
ただ、これだとバッファされるだけで、確実に送信されるわけではない。
なので、直後にflushを呼び出してやり、メッセージ送信を確定させる。

Socket側

同じく、Connectが確定したらメンバ変数に格納する。
・・・まあ、今の書き方はメモリ管理的に確実か微妙なんだけど、動いてるからいいや。

private function socket_connectHandler(event:Event):void
{
	trace( "socket connect" );
	socket = event.target as Socket;
	socket.addEventListener(ProgressEvent.SOCKET_DATA, socket_socketDataHandler);
}

Socket側もConnectイベントでメンバ変数にSocketを確保。
イベント登録や、ボタンの処理はSeverSocket側と同じ。


これでボタンをおすと、お互いのコンソールに"メッセージ"と表示される様になる。


書き込み後のflush呼び出しをすっかり忘れてて、しばらくハマった。
特にLinux->Winがflushなしでも問題なく送信できていたので、
Win->Linuxが送信できない理由がすぐに思いつかなかった。


ファイヤウォールの設定まで見直したよ。


諦めて布団に入ってから、ようやく気づけた・・・

ServerSocket側全ソース

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
	layout="vertical" verticalAlign="middle"
	initialize="initializeLogic()" close="closeLogic()">
	
	<mx:Script>
		<![CDATA[

		private function initializeLogic():void
		{
			try {
				// create server socket
				serverSocket = new ServerSocket();
				serverSocket.bind( 50000 );
				serverSocket.listen();
				serverSocket.addEventListener(ServerSocketConnectEvent.CONNECT, serverSocket_connectHandler);
			}
			catch( e:Error ) {
				trace( e.message );
			}
		}
		
		private function closeLogic():void
		{
			serverSocket.close();
		}
		
		private function sendBtn_clickLogic():void
		{
			if( socket ) {
				socket.writeUTF( "メッセージ" );
				socket.flush();
			}
		}
		
		private function serverSocket_connectHandler(event:ServerSocketConnectEvent):void
		{
			trace( "connect !" );
			socket = event.socket
			socket.addEventListener(ProgressEvent.SOCKET_DATA, socket_socketDataHandler);
		}
		
		private function socket_socketDataHandler(event:ProgressEvent):void
		{
			var sokcet:Socket = event.target as Socket;
			trace( "socket socket data:" + socket.readUTF() );
		}
		
		private var serverSocket:ServerSocket;
		private var socket:Socket;
		]]>
	</mx:Script>
	
	<mx:Button id="sendBtn" label="send" click="sendBtn_clickLogic()" />
	
</mx:WindowedApplication>

Socket側全ソース

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
	layout="vertical" verticalAlign="middle"
	initialize="initializeLogic()" close="closeLogic()">
	
	<mx:Script>
		<![CDATA[

		private function initializeLogic():void
		{
			// create socket
			var socket:Socket = new Socket("192.168.0.5", 50000);
			socket.addEventListener(Event.CONNECT, socket_connectHandler);
			socket.addEventListener(IOErrorEvent.IO_ERROR, socket_ioErrorHandler);
			socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, socket_securityErrorHandler);
		}
		
		private function closeLogic():void
		{
			if ( socket && socket.connected ) {
				socket.close();
			}
		}
		
		private function sendBtn_clickLogic():void
		{
			if ( socket ) {
				socket.writeUTF( "メッセージ" );
				socket.flush();
			}
		}
		
		private function socket_connectHandler(event:Event):void
		{
			trace( "socket connect" );
			socket = event.target as Socket;
			socket.addEventListener(ProgressEvent.SOCKET_DATA, socket_socketDataHandler);
		}
		
		private function socket_ioErrorHandler(event:IOErrorEvent):void
		{
			trace( "socket io error" );
		}
		
		private function socket_securityErrorHandler(event:SecurityErrorEvent):void
		{
			trace( "socket security error" );
		}
		
		private function socket_socketDataHandler(event:ProgressEvent):void
		{
			var sokcet:Socket = event.target as Socket;
			trace( "socket socket data:" + socket.readUTF() );
		}
		
		private var socket:Socket;
		]]>
	</mx:Script>
	
	<mx:Button id="sendBtn" label="send" click="sendBtn_clickLogic()" />
	
</mx:WindowedApplication>