Flex XmlSocket 跨域通信

闲来无事,温习了一下Socket编程,客户端基于FlexBuilder3.0,服务器基于VS2010C#开发。如下运行效果图:

登录界面:

 

登录后界面:

 

如果姓名有重复登录,系统会提示:

 

多个界面交互:

 

服务器截图:

客户端代码:

 

代码
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
  backgroundGradientAlphas
="[1.0, 0.81]" backgroundGradientColors="[#166065, #93F0F6]">
<mx:Style>
 Application{
 fontSize:12px;
 }
</mx:Style>

<mx:Script>
 
<![CDATA[
  import mx.events.FlexEvent;
  import mx.formatters.DateFormatter;
    import flash.events.Event;
       import flash.events.DataEvent;
       import mx.controls.Alert;
       import flash.system.
*;
 
private var socket:XMLSocket;
 
private var mydate:Date=new Date();
 
 
private var formatter:DateFormatter=new DateFormatter();
 
//连接服务器
  private function ConnServer():void{
   
//formatter.formatString="YYYY-MM-DD JJ:NN:SS";
   if(txtIP.text=="" || txtPort.text==''|| userName.text==''){
     Alert.yesLabel
="确定";
     Alert.show(
"不能为空请填写!","提示",1);
     
return;
   }
   formatter.formatString
="JJ:NN:SS";
   currentState
="loginState";
   loginPanel.title
="客户端-"+userName.text;
   socket
=new XMLSocket();
   
//添加事件侦听
   socket.addEventListener(Event.CONNECT,OnConn);
   socket.addEventListener(DataEvent.DATA,OnReceived);
   socket.addEventListener(IOErrorEvent.IO_ERROR,isErrorHandler);
   socket.connect(txtIP.text,
int(txtPort.text));
   
   textReceive.addEventListener(FlexEvent.VALUE_COMMIT,OnValueChange);
  }
  
//设置接收信息区的滚动条
  private function OnValueChange(evt:FlexEvent):void{
   textReceive.verticalScrollPosition
=textReceive.maxVerticalScrollPosition;
  }
  
//连接完成执行函数
  private function OnConn(evt:Event):void{
   textReceive.htmlText
="*******************<font color='#ff0000'>登录成功</font>********************\n";
   
//向服务器发送指令
   socket.send("CONN|"+userName.text);
  }
  
//接收服务器转播信息
  private function OnReceived(evt:DataEvent):void{
   
if(evt.data=="Failed"){//接收失败重新登录连接服务器,客户端转向登录状态
       currentState="";
      loginPanel.title
="客户端-未连接"
      textReceive.text
="";
   Alert.yesLabel
="确定";
    Alert.show(
"姓名【"+userName.text+"】已被占用!","提示",1);
   }else{//接收数据显示在客户端信息区
    var arry:Array=evt.data.split('|',evt.data.length);
    textReceive.text
+=""+arry[0]+" 在"+formatter.format(mydate)+"】说:\n"+arry[1]+"\n";
   }
  }
  
//连接服务器报错处理
  private function isErrorHandler(evt:IOErrorEvent):void{
   currentState
="";
      loginPanel.title
="客户端-未连接"
   Alert.yesLabel
="确定";
   Alert.show(evt.text,
"提示",1,this);
  }
  
//客户端向服务器发送消息
  private function sendMsg():void{
   
if(txtIP.text=="" || txtPort.text==""){
       currentState
="";
       loginPanel.title
="客户端-未连接"
     return;
   }
   
if(socket.connected){
      
if(textSend.text==""){
     Alert.yesLabel
="确定";
     Alert.show(
"发送内容不能为空!","提示",1);
     
return;
     }
    socket.send(userName.text
+"|"+textSend.text); 
    textReceive.text
+=""+userName.text+" 在"+formatter.format(mydate)+"】说:\n"+textSend.text+"\n";
    textSend.text
="";
   }
   
else{
           currentState
="";
       loginPanel.title
="客户端-未连接"
     Alert.yesLabel
="确定";
     Alert.show(
"登录服务器失败,请从新登录!","提示",1);
   }   
  }
 ]]
>
</mx:Script>

<!--登录成功后把Panel的状态设为loginState-->
<mx:states>

 
<mx:State name="loginState">
  
<mx:RemoveChild target="{label1}"/>
  
<mx:RemoveChild target="{txtIP}"/>
  
<mx:RemoveChild target="{txtPort}"/>
  
<mx:RemoveChild target="{label2}"/>
  
<mx:RemoveChild target="{btnCon}"/>
  
<mx:SetProperty target="{textReceive}" name="height" value="212"/>
  
<mx:SetProperty target="{textReceive}" name="y" value="10"/>
  
<mx:RemoveChild target="{label3}"/>
  
<mx:RemoveChild target="{userName}"/>
  
 
</mx:State>
</mx:states>
<!--登录成功后播放2秒钟动画把Panel状态改为loginState-->
  
<mx:transitions>
   
<mx:Transition>  
    
<mx:Iris duration="2000" targets="{[loginPanel]}">
    
</mx:Iris>
   
</mx:Transition>
  
</mx:transitions>
<!--客户端窗口设计-->
 
<mx:Panel id="loginPanel" width="423" height="358" layout="absolute" horizontalCenter="0" y="131" title="客户端" backgroundAlpha="0.8">
  
<mx:TextArea id="textReceive" x="10" y="45" width="383" height="177"/>
  
<mx:TextArea id="textSend" x="10" y="230" width="323" height="76"/>
  
<mx:Button id="btnSend" click="sendMsg()" y="229" label="发送" height="77" x="341" fillAlphas="[1.0, 1.0, 0.9, 0.9]" fillColors="[#25B9BE, #DAE9EA, #148A8E, #3CEEF4]"/>
  
<mx:Label x="10" y="10" text="IP:" fontWeight="bold" id="label1"/>
  
<mx:TextInput id="txtIP" x="35" y="8" width="97" text="192.168.1.35"/>
  
<mx:Label x="134" y="10" text="Port:" fontWeight="bold" id="label2"/>
  
<mx:TextInput id="txtPort" x="170" y="8" width="44" text="1234"/>
  
<mx:Button id="btnCon" click="ConnServer()" x="341" y="9" label="登录" fillAlphas="[1.0, 1.0]" fillColors="[#F8A5BB, #F20C5D]" width="52"/>
  
<mx:Label x="214" y="11" text="姓名:" fontWeight="bold" id="label3"/>
  
<mx:TextInput id="userName" x="255" y="8" width="80" text="风行者"/>
 
</mx:Panel>
 
</mx:Application>

 

 

跨域访问安全沙箱设置:

如果不设置,是不能通信的并且包如下错误:

 

登录客户端时,客户端会向服务器发送字符串:<policy-file-request/>,在服务器端只需检测该字符串,收到后回发一条如下信息:即可解决安全沙箱冲突问题。

                                string onemessage = "<cross-domain-policy><allow-access-from domain=\"" + "*" + "\" to-ports=\"1234\"/></cross-domain-policy>\0";
                                byte[] buffer = Encoding.UTF8.GetBytes(onemessage);
                                socket.Send(buffer);

服务器端代码:请参考以前发表的【C#局域网通信】(C#.net分类里)

http://www.cnblogs.com/Xingsoft-555/archive/2009/12/13/1622829.html

posted @ 2010-12-24 14:58  Xingsoft  阅读(1736)  评论(1编辑  收藏  举报