今天我们的讲解的是在昨天代码的功能上加上在线列表的功能,同时会去掉共享对象,用另一种方法向客户端发消息.
先看看服务端代码我们更改些什么代码:
application.onAppStart = function() { this.chatMsgArray = new Array(); this.userListArray = new Array(); } application.onConnect = function(client, userName) { if(checkOnline(userName)){ this.rejectConnection(client); return; } this.acceptConnection(client); client.userName = userName; this.userListArray.push(userName); sendUserList(); //客户端调用方法 client.getMsg = function(){ return application.chatMsgArray; } client.sendMsg = function(msg){ var chatInfo = this.userName + " : " + msg; application.chatMsgArray.push(chatInfo); sendMsgToClient(chatInfo); } } application.onDisconnect = function(client) { trace("用户:"+client.userName+" 离开"); var len = this.userListArray.length; for(var i=0;i<len;i++){ if(this.userListArray[i] == client.userName){ this.userListArray.splice(i,1); sendUserList(); } } } application.onAppStop = function() { delete this.chatMsg_so; } function checkOnline(userName){ var len = application.userListArray.length; for(var i=0;i<len;i++){ if(application.userListArray[i] == userName){ return true; } } return false; } function sendMsgToClient(chatInfo){ var len = application.clients.length; for(var i=0;i<len;i++){ application.clients[i].call("getMsgInfo",null,chatInfo); } } function sendUserList(){ var len = application.clients.length; for(var i=0;i<len;i++){ application.clients[i].call("getUserList",null,application.userListArray); } }
this.chatMsgArray = new Array();
this.userListArray = new Array();
这两个定义的数组是在开始定义的,chatMsgArray是存储所有的聊天信息,userListArray是一个存储在线列表的数组
当用户连接进来的时候,我们用了一个函数checkOnline来检查用户是不是在在线列表中,如果在就用this.rejectConnection(client);拒绝这个连接,如果不在就接受这个连接并加到在线列表中
sendUserList函数是向所以客户端发送在线列表信息,application.clients是一个存储所以客户端连接的信息,application.clients.call就是调用客户端函数,使用方法跟客户端调服务器端是一样的.
然后我们增加了1个供客户端调用的函数
client.getMsg = function(){ return application.chatMsgArray; }
client.getMsg是返回所有的聊天信息,当用户第一次连接时,得到别人的聊天记录
在用户断开连接的时候增加了将断线用户从在线列表中清除,并且发送在线列表.
再来看看客户端代码:
package net.smilecn.chat{ import flash.display.Sprite; import flash.net.NetConnection; import flash.net.Responder; import flash.events.NetStatusEvent; import flash.events.SyncEvent; import flash.events.MouseEvent; import fl.controls.TextArea; import fl.controls.Button; import fl.controls.TextInput; import fl.controls.Label; import fl.controls.List; import fl.data.DataProvider; public class Chat extends Sprite{ private var nc:NetConnection; private var rtmpUrl:String = "rtmp://localhost/chat"; private var msg:Label; private var userNameInput:TextInput; private var enterBtn:Button; private var button:Button; private var textArea:TextArea; private var textInput:TextInput; private var userList:List; private var userName:String = "user002"; public function Chat():void{ userNameInput = new TextInput(); userNameInput.move(100,200); addChild(userNameInput); enterBtn = new Button(); enterBtn.move(220,200); enterBtn.label = "进入"; addChild(enterBtn); enterBtn.addEventListener(MouseEvent.CLICK,enterBtnClickHandler); msg = new Label(); msg.move(100,230); msg.text = ""; addChild(msg); } private function enterBtnClickHandler(event:MouseEvent):void{ if(userNameInput.text!=""){ userName = userNameInput.text; removeChild(userNameInput); removeChild(enterBtn); removeChild(msg); textArea=new TextArea(); textArea.setSize (200,300); textArea.move (20,20); addChild (textArea); textInput=new TextInput(); textInput.width = 140; textInput.move (20,330); addChild (textInput); button=new Button(); button.width=50; button.label="发送"; button.move (170,330); addChild(button); button.addEventListener (MouseEvent.CLICK,sendMsg); userList = new List(); userList.move(250,20); userList.setSize(100,300); addChild(userList); nc=new NetConnection(); nc.addEventListener (NetStatusEvent.NET_STATUS,netStatusHandler); nc.connect (rtmpUrl,userName); nc.client = this; }else{ msg.text = "请输入用户名"; } } private function netStatusHandler(event:NetStatusEvent):void{ trace("event.info.code:",event.info.code); if(event.info.code == "NetConnection.Connect.Success"){ nc.call("getMsg",new Responder(getMsgResult,getMsgFault)) } } private function getMsgResult(re:Array):void{ var s:String=""; var len:Number = re.length; for(var i=0;i<len;i++){ s += re[i]+" "; } textArea.text = s; } private function getMsgFault(fe:*):void{ trace(fe); } private function sendMsg (e:MouseEvent):void{ nc.call("sendMsg",null,textInput.text); textInput.text = ""; } public function getMsgInfo(msg:String):void{ textArea.appendText(msg+" "); } public function getUserList(list:Array):void{ userList.dataProvider = new DataProvider(list); } } }
客户端首先增加了一个用户输入名字,这是些简单的代码.
然后共享对象的那部份去掉了,加了句这样的代码:nc.client = this;
这句话的意思是指定当前对象为服务器回调方法的对象
public function getMsgInfo(msg:String):void{ textArea.appendText(msg+"\n"); } public function getUserList(list:Array):void{ userList.dataProvider = new DataProvider(list); }
这两个方法就是服务器调用的方法.
在nc连接成功的地方加了句nc.call(”getMsg”,new Responder(getMsgResult,getMsgFault)),这句是在刚连接成功的时候得到以前用户的聊天记录.
顺便说一句,客户端代码用到了组件,所以要把这些组件放到库中才能运行,上一节也是这样的.
下节继续.
(本教程如需转载请注明出处!)