AIR.簡易Messengerを作る その2
まずはSearchボタン周りから作る。
node検出用メッセージの送信、待ち受け、返信の処理は、
DatagramSocketで試してた内容を、ほぼそのまま移植。
コメントの追加と、繰り返し使う値を定数宣言して運用。
ListはArrayCollectionにバインド。
... private const nodes:ArrayCollection = new ArrayCollection( ["192.168.0.10"] ); ... <mx:List id="nodeList" width="100%" height="60%" dataProvider="{nodes}"/>
未だにこの書き方が正しいのか分かりませんが、
警告も出ないし、ちゃんと動くのでよかろーよ。
Linuxからbroadcastができないので、
nodesメンバにあらかじめIPアドレスを入れておくことにします。
Searchボタン押下処理で中身をクリアして・・・
private function searchBtn_clickLogic():void { ... nodes.removeAll(); ... }
datagramSocketの受信ハンドラで、node検出用メッセージの返信なら、
データとしてIPアドレスを確保します。
private function datagramSocket_dataHandler(event:DatagramSocketDataEvent):void { ... // メッセージを確保 var msg:String = event.data.readUTF(); // broadcastメッセージか判定 if( msg == MSG_SEARCH_NODE ) { ... } else { // broadcastメッセージの返信なので、 // 送信元のIPアドレスをnode一覧に追加する nodes.addItem( event.srcAddress ); } ... }
これでsearchボタンの機能が完成。
broadcastメッセージが自分自身にも届くため、
リストに自分自身のIPアドレスも表示されますが、まあ、よしとしましょう。
その他調整
<mx:WindowedApplication ... width="450" height="400" ...>
Windowsで見たときサイズが大きすぎたので、指定。
モニターのドットピッチがかなり異なることを考慮してなかった。
簡易Messenger全ソース
<?xml version="1.0" encoding="utf-8"?> <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" horizontalAlign="left" showStatusBar="false" fontSize="20" width="450" height="400" initialize="initializeLogic()" close="closeLogic()"> <!-- logic --> <mx:Script> <![CDATA[ import mx.collections.ArrayCollection; //-------------------------------------------------------------------------------------- // constants //-------------------------------------------------------------------------------------- /** node検出のbroadcastに使うポート */ static private const PORT_BROADCAST:int = 50000; /** node検出用にbroadcastするメッセージ */ static private const MSG_SEARCH_NODE:String = "message search node"; /** node検出メッセージに対して、返信するメッセージ */ static private const MSG_NODE_RES:String = "message node res"; //-------------------------------------------------------------------------------------- // logics //-------------------------------------------------------------------------------------- /** application initialize */ private function initializeLogic():void { try { // broadcastの受信開始 datagramSocket = new DatagramSocket(); datagramSocket.addEventListener(DatagramSocketDataEvent.DATA, datagramSocket_dataHandler); datagramSocket.bind( PORT_BROADCAST ); datagramSocket.receive(); } catch( e:Error ) { trace( e.message ); } } /** application close */ private function closeLogic():void { // リソース開放 datagramSocket.close(); } /** search button click */ private function searchBtn_clickLogic():void { try { // node情報をクリアする nodes.removeAll(); // node検出用メッセージをbroadcast var ba:ByteArray = new ByteArray(); ba.writeUTF( MSG_SEARCH_NODE ); datagramSocket.send(ba, 0, 0, "192.168.0.255", PORT_BROADCAST); } catch( e:Error ) { trace( e.message ); // Linuxはsendで例外 AIR 2.0 beta2 } } /** send button click */ private function sendBtn_clickLogic():void { } //-------------------------------------------------------------------------------------- // handlers //-------------------------------------------------------------------------------------- /** datagram socket data */ private function datagramSocket_dataHandler(event:DatagramSocketDataEvent):void { try { // メッセージを確保 var msg:String = event.data.readUTF(); // broadcastメッセージか判定 if( msg == MSG_SEARCH_NODE ) { // node検出用のbroadcastメッセージなので、返信する // 送信データ作成 var ba:ByteArray = new ByteArray(); ba.writeUTF( MSG_NODE_RES ); // 送信 event.target.send(ba, 0, 0, event.srcAddress, PORT_BROADCAST); } else { // broadcastメッセージの返信なので、 // 送信元のIPアドレスをnode一覧に追加する nodes.addItem( event.srcAddress ); } } catch( e:Error ) { trace( e.message ); } } //-------------------------------------------------------------------------------------- // private members //-------------------------------------------------------------------------------------- /** broadcast用 */ private var datagramSocket:DatagramSocket; /** ローカルネット内のPC */ private const nodes:ArrayCollection = new ArrayCollection( ["192.168.0.10"] ); ]]> </mx:Script> <!-- components --> <mx:Button label="Search" width="140" click="searchBtn_clickLogic()"/> <mx:List id="nodeList" width="100%" height="60%" dataProvider="{nodes}"/> <mx:TextArea id="textArea" width="100%" height="40%"/> <mx:Button label="Send" width="100%"/> </mx:WindowedApplication>