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コンポーネントを作るところまでしたい。

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

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

Leave a Reply