[ruby][flex] Socketサーバを書いてみた

このエントリーを含むはてなブックマーク

FlexでXMLSocketする必要があったので、テスト用にサーバを書いてみたよ。 自信はないので、1%も保証はないけど一応動く。

sockettest1pnf.png

sockettest2.png

ソースファイル

まずはRubyのソース

server_client.rb

  1. require "socket_server"
  2. server = SocketServer.new
  3. server.open 8001


ソケットサーバを8001番ポートでオープン

socket_server.rb

  1. class SocketServer
  2.  
  3.   def initialize( port=nil )
  4.     puts "create server.."
  5.     @port = port || 8001;
  6.   end
  7.  
  8.   def open( port=nil )
  9.     @port = port if( !port.nil? )
  10.     @gs = TCPServer.open @port
  11.     @clients = []
  12.     puts "open server #{@port}"
  13.  
  14.     while true
  15.       Thread.start( @gs.accept ) do |s|
  16.         open_client s
  17.         while ( message = s.gets )
  18.           send_message_all( message )
  19.         end
  20.         close_client s
  21.       end
  22.     end
  23.  
  24.   end
  25.  
  26.   def open_client( client )
  27.     puts "#{client} is connected."
  28.     @clients <<client
  29.   end
  30.  
  31.   def close_client( client )
  32.     puts "#{client} is closed."
  33.     @clients.delete client
  34.   end
  35.  
  36.   def send_message_all( message )
  37.     puts "[message all] #{message}"
  38.     @clients.each do |client|
  39.       send_message( client, message )
  40.     end
  41.   end
  42.  
  43.   # send message to IOSocket
  44.   def send_message( target, message )
  45.     message.chomp!
  46.     target.write( message <<"\n" )
  47.   end
  48.  
  49. end


そしてFlex2のソース

Socketクラスを使ってます。 XMLSocketクラスを使ったら、メッセージのタイミングが1個ずれました。

SocketTest.mxml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <mx:Application
  3.   xmlns:mx="http://www.adobe.com/2006/mxml"
  4.   xmlns:views="views.*"
  5.   creationComplete="{handleCreateComplete()}"
  6.  >
  7.  
  8.   <mx:Script>
  9.     <![CDATA[
  10.       import flash.net.Socket;
  11.  
  12.       [Bindable]
  13.       public var sock:Socket;
  14.  
  15.       private function handleCreateComplete():void
  16.       {
  17.         sock = new Socket();
  18.         sock.addEventListener(ProgressEvent.SOCKET_DATA,handleSocketData);
  19.         sock.addEventListener(Event.CONNECT,handleSocketConnect);
  20.         sock.addEventListener(Event.CLOSE,handleSocketClose);
  21.         //sock.addEventListener(DataEvent.DATA,handleSocketData);
  22.         sock.addEventListener(IOErrorEvent.IO_ERROR,handleSocketIOError);
  23.       }
  24.  
  25.       private function handleSocketConnect(e:Event):void
  26.       {
  27.         debugger.text += "Connection Success.\n";
  28.         formViewStack.selectedChild = connectedForm;
  29.         sock.removeEventListener(Event.CONNECT,arguments.callee);
  30.       }
  31.  
  32.       private function handleSocketClose(e:Event):void
  33.       {
  34.         debugger.text += "Connection Close.\n";
  35.         formViewStack.selectedChild = connectForm;
  36.         sock.removeEventListener(Event.CLOSE,arguments.callee);
  37.       }
  38.  
  39.       private function handleSocketData(e:ProgressEvent):void
  40.       {
  41.         debugger.text += e.target.readUTF();
  42.       }
  43.  
  44.       private function handleSocketIOError(e:IOError):void
  45.       {
  46.         trace(e);
  47.       }
  48.  
  49.     ]]>
  50.   </mx:Script>
  51.  
  52.   <mx:Panel x="58" y="57" width="300" height="300" title="Socket Client">
  53.  
  54.     <mx:VDividedBox width="100%" height="100%">
  55.  
  56.       <mx:ViewStack id="formViewStack" width="100%" height="200">
  57.  
  58.         <views:ConnectForm id="connectForm" sock="{sock}" />
  59.         <views:ConnectionForm id="connectedForm" sock="{sock}" />
  60.  
  61.       </mx:ViewStack>
  62.  
  63.       <mx:TextArea width="100%" id="debugger"/>
  64.  
  65.     </mx:VDividedBox>
  66.  
  67.   </mx:Panel>
  68.  
  69. </mx:Application>


views.ConnectForm.mxml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml">
  3.   <mx:Script>
  4.     <![CDATA[
  5.       public var sock:Socket;
  6.  
  7.       private function handleConnectButtonClick(e:MouseEvent):void
  8.       {
  9.         sock.connect( formdata.host, formdata.port );
  10.       }
  11.  
  12.     ]]>
  13.   </mx:Script>
  14.  
  15.   <mx:Model id="formdata">
  16.     <root>
  17.       <host>{txtHost.text}</host>
  18.       <port>{int(txtPort.text)}</port>
  19.     </root>
  20.   </mx:Model>
  21.  
  22.   <mx:Form>
  23.     <mx:FormItem label="host">
  24.       <mx:TextInput id="txtHost" text="localhost"/>
  25.     </mx:FormItem>
  26.     <mx:FormItem label="port">
  27.       <mx:TextInput id="txtPort" text="8001"/>
  28.     </mx:FormItem>
  29.     <mx:FormItem>
  30.       <mx:Button label="接続" click="{handleConnectButtonClick(event)}"/>
  31.     </mx:FormItem>
  32.   </mx:Form>
  33.  
  34. </mx:Canvas>


views.ConnectionForm.mxml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml">
  3.   <mx:Script>
  4.     <![CDATA[
  5.  
  6.       public var sock:Socket;
  7.  
  8.       private function handleSendButtonClidk(e:MouseEvent):void
  9.       {
  10.         if( sock.connected )
  11.         {
  12.           XML.prettyPrinting = false;
  13.           sock.writeUTF( sendXML.toXMLString() + "\n" );
  14.           sock.flush();
  15.         }
  16.       }
  17.  
  18.     ]]>
  19.   </mx:Script>
  20.  
  21.   <mx:XML id="sendXML" xmlns="">
  22.     <root>
  23.       <message>{txtMessage.text}</message>
  24.     </root>
  25.   </mx:XML>
  26.  
  27.   <mx:Form>
  28.     <mx:FormItem label="Message">
  29.       <mx:TextInput id="txtMessage" />
  30.     </mx:FormItem>
  31.     <mx:FormItem>
  32.       <mx:Button label="send" click="{handleSendButtonClidk(event)}"/>
  33.     </mx:FormItem>
  34.   </mx:Form>
  35. </mx:Canvas>


とりあえず、ここまで

最終的には、mx.rpc.AbstractInvokaを継承したSocketServiceコンポーネントを作るところまでしたい。

Posted in actionscript3.0, flex, ruby, 日記 at 10月 30th, 2007. Trackback URI: trackback

No Responses to “[ruby][flex] Socketサーバを書いてみた”

Leave a Reply