客户端代码如下
代码如下
loginWin.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:TitleWindow xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="320" height="158" title="用户登录"
fontSize="12" borderColor="#33909E">
<mx:Label x="39.5" y="27" text="登录名:"/>
<mx:TextInput x="100.5" y="25" id="userName_txt"/>
<mx:Button x="100.5" y="66" label="确 定" id="ok" />
<mx:StringValidator source="{userName_txt}" property="text" required="true" requiredFieldError="登录名不能为空" />
</mx:TitleWindow>
SocketExample.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" fontSize="12" creationComplete="init()" >
<mx:Script>
<![CDATA[
import mx.utils.StringUtil;
import mx.events.IndexChangedEvent;
import mx.managers.PopUpManager;
import mx.controls.Alert;
//连接服务器地址
private static const SERVER_HOST:String = "127.0.0.1";
//连接服务器端口
private static const SERVER_PORT:Number = 9999 ;
private var socket:Socket = new Socket();
// 用户登录消息头
public static const LOGIN_HEAD:String = "0";
// 发送普通消息头
public static const MESSAGE_HEAD:String = "1";
// 客户端人数消息头
public static const CLIENT_NUM_HEAD:String = "2";
// 客户端离开消息头
public static const LOGIN_OUT_HEAD:String= "3";
//如果是用户列表消息头
public static const USER_LIST:String = "4";
//说话标记 格式 XXX:aa 表示 XXX说aa
public static const SAY_STATE:String = ":";
//在onbeforeunload事件中释放socket连接脚本
private static const FUN_CLOSE:String = ""
+ "document.insertScript = function() { \n"
+ " window.onbeforeunload = function(){ \n"
+ " return SocketExample.doClose() ; \n"
+ " } \n"
+ "} \n";
private var myWin:loginWin = new loginWin() ;
private var userName:String ;
//加载完毕执行方法
private function init():void{
//设置登录窗口位置
myWin.x = (this.x+this.width-myWin.width)/2 ;
myWin.y = (this.y+this.height-myWin.height)/2 ;
//弹出登录窗口
PopUpManager.addPopUp(myWin,this,true);
//为 登录窗口 确定按钮添加单击事件监听
myWin.ok.addEventListener(MouseEvent.CLICK,doOK);
//动态添加javascript事件
ExternalInterface.call(FUN_CLOSE) ;
//监听关闭窗口事件 注意:doClose是暴露在javascript中的方法 ,该方法调用ActionScript中的doASClose方法
(回调函数)
ExternalInterface.addCallback("doClose",doASClose);
}
//点击输入用户名窗口确定按钮事件处理方法
private function doOK(event:MouseEvent):void{
//获得输入的用户登录名 不能为空
userName =myWin.userName_txt.text.toString();
if(userName == ""){
Alert.show("登录名不能为空!","提示");
return ;
}
//验证通过之后 移除登录窗口
PopUpManager.removePopUp(myWin);
//执行连接,向服务端的ServiceSocket的9999端口发送连接请求,服务端就会分配一个端口给客户端使用
socket.connect(SERVER_HOST,SERVER_PORT);
//监听连接成功事件
socket.addEventListener(Event.CONNECT,conn);
//监听服务器发送信息;
socket.addEventListener(ProgressEvent.SOCKET_DATA,getServerMsg);
//监听socket链接关闭事件
socket.addEventListener(Event.CLOSE,socketClose);
}
//连接成功事件
private function conn(event:Event):void{
this.server.text += " -- 连接服务器成功! --\n";
this.t_name.text = this.userName ;
//连接成功之后,发送用户登录消息给服务器
this.sendMessage(LOGIN_HEAD+userName);
}
//接受服务器信息;由服务端的socket的getOutputStream发送数据
private function getServerMsg(event:ProgressEvent):void{
if(socket!=null && socket.connected){
var aMsg:Array = null;
var message:String = null ;
var kk:uint = 0 ;
//循环读取数据,socket的bytesAvailable对象存放了服务器传来的所有数据
while(socket.bytesAvailable){
//使用utf8格式,避免中文乱码
message = socket.readMultiByte(socket.bytesAvailable,"utf8") ;
//获得消息数组
aMsg = message.split('\n');
if(aMsg!=null&&aMsg.length>0){
//循环消息数组
for(var i:uint=0; i<aMsg.length ;i++){
var tmp_str:String = StringUtil.trim(aMsg[i]);
//在内容区域显示内容
//获得消息头
var head:String = tmp_str.substring(0,1);
//获得消息体
var body:String = tmp_str.substring(1);
if(head == LOGIN_HEAD){
//登录消息
server.text += body + ' 上线了!\n';
this.server.verticalScrollPosition =
this.server.maxVerticalScrollPosition;
}else if(head == MESSAGE_HEAD){
//如果是普通消息
//滚动到最下面
//是谁说的
var who:String = body.substring(0,body.indexOf(SAY_STATE));
//说的什么话
var say_word:String = body.substring(body.indexOf(SAY_STATE)
+1);
this.t_content.text += who+" 说:"+ say_word +'\n';
this.t_content.verticalScrollPosition =
this.t_content.maxVerticalScrollPosition;
}else if(head == CLIENT_NUM_HEAD){
//如果是客户端人数消息
client_num.text = "在线人数:"+body ;
}else if(head == LOGIN_OUT_HEAD){
//如果是客户端离开消息
server.text += body +' 离开了!\n';
this.server.verticalScrollPosition =
this.server.maxVerticalScrollPosition;
}else if(head == USER_LIST){
//如果是用户列表消息
var userArr:Array = body.split("-");
state.dataProvider = userArr ;
this.state.verticalScrollPosition =
this.state.maxVerticalScrollPosition;
}
}
}
}
}
}
//socket链接关闭方法
private function socketClose(event:Event):void{
//如果是客户端离开消息
this.server.text += " -- 服务器连接已关闭! --\n";
}
//发送消息方法
public function sendMessage(msg:String):void{
//新建一个ByteArray来存放数据
var message:ByteArray=new ByteArray();
//写入数据,使用writeUTFBytes以utf8格式传数据,避免中文乱码
message.writeUTFBytes(msg+"\n");
//写入socket的缓冲区
socket.writeBytes(message);
//调用flush方法发送信息
socket.flush();
//清空消息框
this.t_word.text="";
}
//监听 窗口关闭事件 释放socket连接
private function doASClose():String{
if(this.socket != null){
this.socket.close() ;
}
this.socket = null ;
return "";
}
]]>
</mx:Script>
<mx:Panel width="95%" height="95%" layout="absolute" horizontalCenter="0" verticalCenter="0" title="网络聊天室">
<mx:HBox y="0" x="0" width="100%" height="100%">
<mx:VBox height="95%" width="70%" horizontalAlign="center" verticalAlign="middle">
<mx:Spacer height="3%"/>
<mx:TextArea width="95%" height="85%" id="t_content" editable="false" enabled="true"/>
<mx:HBox width="95%">
<mx:Label width="40" text="帅哥" id="t_name"/>
<mx:Label text="说:"/>
<mx:TextInput width="85%" id="t_word"/>
<mx:Button label="发送" id="myBtn" click="sendMessage
(MESSAGE_HEAD+t_name.text+SAY_STATE+t_word.text)"/>
</mx:HBox>
</mx:VBox>
<mx:VBox height="95%" width="30%" horizontalAlign="center" verticalAlign="top">
<mx:Label text="在线用户:0" id="client_num"/>
<mx:List width="95%" height="95%" editable="false" id="state"/>
<mx:TextArea id="server" editable="false" height="100%" width="95%"/>
</mx:VBox>
</mx:HBox>
</mx:Panel>
</mx:Application>
浙公网安备 33010602011771号