今天我们的讲解的是在昨天代码的功能上加上在线列表的功能,同时会去掉共享对象,用另一种方法向客户端发消息.
先看看服务端代码我们更改些什么代码:
- 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)),这句是在刚连接成功的时候得到以前用户的聊天记录.
顺便说一句,客户端代码用到了组件,所以要把这些组件放到库中才能运行,上一节也是这样的.
下节继续.
(本教程如需转载请注明出处!)