Home > ruby | flex | actionscript3.0 | 日記 > [ruby][flex] Socketサーバを書いてみた

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

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

sockettest1pnf.png

sockettest2.png

ソースファイル

まずはRubyのソース

server_client.rb

require "socket_server"
server = SocketServer.new
server.open 8001

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

socket_server.rb

class SocketServer
 
  def initialize( port=nil )
    puts "create server.."
    @port = port || 8001;
  end
 
  def open( port=nil )
    @port = port if( !port.nil? )
    @gs = TCPServer.open @port
    @clients = []
    puts "open server #{@port}"
   
    while true
      Thread.start( @gs.accept ) do |s|
        open_client s
        while ( message = s.gets )
          send_message_all( message )
        end
        close_client s
      end
    end
   
  end
 
  def open_client( client )
    puts "#{client} is connected."
    @clients <<client
  end
 
  def close_client( client )
    puts "#{client} is closed."
    @clients.delete client
  end
 
  def send_message_all( message )
    puts "[message all] #{message}"
    @clients.each do |client|
      send_message( client, message )
    end
  end
 
  # send message to IOSocket
  def send_message( target, message )
    message.chomp!
    target.write( message <<"\n" )
  end
 
end

そしてFlex2のソース

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

SocketTest.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Application
  xmlns:mx="http://www.adobe.com/2006/mxml"
  xmlns:views="views.*"
  creationComplete="{handleCreateComplete()}"
 >

 
  <mx:Script>
    <![CDATA[
      import flash.net.Socket;
     
      [Bindable]
      public var sock:Socket;
     
      private function handleCreateComplete():void
      {
        sock = new Socket();
        sock.addEventListener(ProgressEvent.SOCKET_DATA,handleSocketData);
        sock.addEventListener(Event.CONNECT,handleSocketConnect);
        sock.addEventListener(Event.CLOSE,handleSocketClose);
        //sock.addEventListener(DataEvent.DATA,handleSocketData);
        sock.addEventListener(IOErrorEvent.IO_ERROR,handleSocketIOError);
      }
     
      private function handleSocketConnect(e:Event):void
      {
        debugger.text += "Connection Success.\n";
        formViewStack.selectedChild = connectedForm;
        sock.removeEventListener(Event.CONNECT,arguments.callee);
      }
     
      private function handleSocketClose(e:Event):void
      {
        debugger.text += "Connection Close.\n";
        formViewStack.selectedChild = connectForm;
        sock.removeEventListener(Event.CLOSE,arguments.callee);
      }
     
      private function handleSocketData(e:ProgressEvent):void
      {
        debugger.text += e.target.readUTF();
      }
     
      private function handleSocketIOError(e:IOError):void
      {
        trace(e);
      }
     
    ]]>

  </mx:Script>
 
  <mx:Panel x="58" y="57" width="300" height="300" title="Socket Client">
   
    <mx:VDividedBox width="100%" height="100%">
     
      <mx:ViewStack id="formViewStack" width="100%" height="200">
       
        <views:ConnectForm id="connectForm" sock="{sock}" />
        <views:ConnectionForm id="connectedForm" sock="{sock}" />
       
      </mx:ViewStack>
     
      <mx:TextArea width="100%" id="debugger"/>
     
    </mx:VDividedBox>
   
  </mx:Panel>
 
</mx:Application>

views.ConnectForm.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml">
  <mx:Script>
    <![CDATA[
      public var sock:Socket;
     
      private function handleConnectButtonClick(e:MouseEvent):void
      {
        sock.connect( formdata.host, formdata.port );
      }
     
    ]]>

  </mx:Script>
 
  <mx:Model id="formdata">
    <root>
      <host>{txtHost.text}</host>
      <port>{int(txtPort.text)}</port>
    </root>
  </mx:Model>
 
  <mx:Form>
    <mx:FormItem label="host">
      <mx:TextInput id="txtHost" text="localhost"/>
    </mx:FormItem>
    <mx:FormItem label="port">
      <mx:TextInput id="txtPort" text="8001"/>
    </mx:FormItem>
    <mx:FormItem>
      <mx:Button label="接続" click="{handleConnectButtonClick(event)}"/>
    </mx:FormItem>
  </mx:Form>
 
</mx:Canvas>

views.ConnectionForm.mxml

<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml">
  <mx:Script>
    <![CDATA[
     
      public var sock:Socket;
     
      private function handleSendButtonClidk(e:MouseEvent):void
      {
        if( sock.connected )
        {
          XML.prettyPrinting = false;
          sock.writeUTF( sendXML.toXMLString() + "\n" );
          sock.flush();
        }
      }
     
    ]]>

  </mx:Script>
 
  <mx:XML id="sendXML" xmlns="">
    <root>
      <message>{txtMessage.text}</message>
    </root>
  </mx:XML>
 
  <mx:Form>
    <mx:FormItem label="Message">
      <mx:TextInput id="txtMessage" />
    </mx:FormItem>
    <mx:FormItem>
      <mx:Button label="send" click="{handleSendButtonClidk(event)}"/>
    </mx:FormItem>
  </mx:Form>
</mx:Canvas>

とりあえず、ここまで

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

Comments:0

Comment Form
Remember personal info

Trackbacks:0

Trackback URL for this entry
http://www.func09.com/wordpress/archives/154/trackback
Listed below are links to weblogs that reference
[ruby][flex] Socketサーバを書いてみた from func09

Home > ruby | flex | actionscript3.0 | 日記 > [ruby][flex] Socketサーバを書いてみた

Search
Feeds
Meta

Return to page top