[FMS]一步一步学Flash Media Server(五)

本文介绍了一个简单的在线聊天室实现方案,包括服务端与客户端代码。通过去除共享对象,并新增在线列表功能,使得用户能够查看当前在线人员及历史聊天记录。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天我们的讲解的是在昨天代码的功能上加上在线列表的功能,同时会去掉共享对象,用另一种方法向客户端发消息.

先看看服务端代码我们更改些什么代码:

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)),这句是在刚连接成功的时候得到以前用户的聊天记录.

顺便说一句,客户端代码用到了组件,所以要把这些组件放到库中才能运行,上一节也是这样的.

下节继续.

(本教程如需转载请注明出处!)

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值