2011年8月27日 星期六

AS3 SOCKET[client]

aS3使用socket連線,這裡提供client端的作法
基本上 client沒有要注意的事項
as3在建立socket連線之後,會自動發送給server(如果有連上的話) <policy-file-request/> 的訊息
之後server會回傳 <cross-domain-policy>...
確定允許連線之後就可正常連線了。
我在寫這個sample的時後,是使用c#當server,由client主動發送<policy-file-request/>的訊息
而server回傳<cross-domain-policy>的這段訊息 則是以字串的方式直接回傳
※官方文件上有說明,正常的流程是在server domain底下放置crossdomain.xml,
以自動確定允許連線。
client也可以自已載入policy檔,方式如下
import flash.system.Security;
Security.loadPolicyFile("http://" + serverURL + "/crossdomain.xml");
但我沒這麼做,我直接以字串的方式將policy的資訊回傳給client~
以下是sample


<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
         xmlns:s="library://ns.adobe.com/flex/spark" 
         xmlns:mx="library://ns.adobe.com/flex/mx" width="500" height="250">
  <fx:Script>
    <![CDATA[
      private var server_ip:String;
      private var server_port:int;
      private var socket:XMLSocket;
      private var policyFlag:Boolean = false;
      private var userName:String;
      private function connect():void
      {
        server_ip=serverAddress.text;
        server_port=int(serverPort.text);
        createSocket();
      }
      private function createSocket():void
      {
        if(server_ip==""||!server_port)
          console("ip or port setting error");
        socket = new XMLSocket();
        System.useCodePage = true;
        //當這個屬性設定為 true 時,會使用應用程式執行所在作業系統的傳統字碼頁來解譯外部文字檔
        socket.addEventListener(Event.CONNECT, onConnect);
        socket.addEventListener(IOErrorEvent.IO_ERROR, failConnect);
        socket.addEventListener(DataEvent.DATA, onDatas);
        socket.connect(server_ip,server_port);
      }
      
      private function onConnect(myStatus:Event):void {
        if (!policyFlag){
          socket.send("<policy-file-request/>");
        }
      }
      
      private function failConnect(myStatus:Event):void {
        console("failConnect");
      }
      
      private function onDatas(event:DataEvent):void {
        if (event.data.substring(0, 21) == "<cross-domain-policy>" && !policyFlag){
          policyFlag = true;
          console("login server");
          userName="user"+int(Math.random()*1000);
          UserToserver("login",userName);
        } else if (event.data)
          packProceser(event.data);
      }
      
      public function UserToserver(pack:String, data:String = ""):void{
        socket.send(pack + " " + data);
      }
      
      public function packProceser(packStr:String):void
      {
        var pack_arr:Array = packStr.split(" ");
        var cmd:String=pack_arr[0];
        switch(cmd)
        {
          case "login":
            console(pack_arr[1]+" login");
            break;
          case "message":
            console(pack_arr[1]);
            break;
        }
      }
      
      private function sendMessage():void
      {
        UserToserver("message",userName+":"+input_txt.text);
      }
      
      private function console(m:String):void
      {
        content_txt.appendText(m+"\n");
      }
    ]]>
  </fx:Script>
  <mx:VBox verticalCenter="0" horizontalCenter="0" verticalAlign="middle" horizontalAlign="left">
    <s:Label fontSize="30" text="SOCKET SAMPLE"/>
  <mx:HBox verticalAlign="middle" horizontalAlign="center">    
  <s:Label text="login server:"/>
    <s:Label text="ip"/>
    <s:TextInput id="serverAddress" text="127.0.0.1"/>
    <s:Label text="port"/>
    <s:TextInput id="serverPort" text="843"/>
    <s:Button label="connect" click="connect()"/>
  </mx:HBox>
    <s:TextArea id="content_txt" width="461"/>
    <mx:HBox>
      <s:TextInput id="input_txt" width="200"/>
      <s:Button label="send" click="sendMessage()"/>
    </mx:HBox>
  </mx:VBox>
</s:Application>

1 則留言:

  1. 感謝你的文~最近也是在研究Socket 不過並不是很順利 看你的文章有點收穫

    回覆刪除