在上一节中,我们学会了在FMS中使用类,虽然不是正式意义上的类,但也会使我们的程序看起来更结构化,这一节我们继续用类的方式改造之前的代码,首先我们要加个用户类(User.asc):
- function User(client,userName){
- this.client = client;
- this.userName = this.client.userName = userName;
- }
很简单的一个类,只有构造,没有方法,其实是当用户的信息更多时,我们通常会将用户的所有信息都封装起来,这样便于我们使用,这里我们只是比前面多加了一个client对象,这个对象是代表连接进来的客户端,我们把它封装到User里面.
接着,UserList.asc也要做相应该的修改,并且把之前在main.asc里面的sendUserList和sendMsgToClient也封装到UserList这个类中.
- function UserList(){
- this.listArray = [];//也可以用new Array(),不过听说[]效率更高;
- }
-
- UserList.prototype.addUser = function(user){
- this.listArray.push(user);
- this.sendUserList();
- }
-
- UserList.prototype.delUser = function(userName){
- var len = this.listArray.length;
- for(var i=0;i<len;i++){
- if(this.listArray[i].userName == userName){
- this.listArray.splice(i,1);
- break;
- }
- }
- this.sendUserList();
- }
-
- UserList.prototype.checkOnline = function(userName){
- var len = this.listArray.length;
- for(var i=0;i<len;i++){
- if(this.listArray[i].userName == userName){
- return true;
- }
- }
- return false;
- }
-
- UserList.prototype.getUserList = function(){
- var result = [];
- var len = this.listArray.length;
- for(var i= 0;i<len;i++){
- result.push(this.listArray[i].userName);
- }
- return result;
- }
-
- UserList.prototype.sendUserList = function(){
- var len = this.listArray.length;
- for(var i=0;i<len;i++){
- this.listArray[i].client.call("getUserList",null,this.getUserList());
- }
- }
-
- UserList.prototype.sendMsgToClient = function(chatInfo){
- var len = this.listArray.length;
- for(var i=0;i<len;i++){
- this.listArray[i].client.call("getMsgInfo",null,chatInfo);
- }
- }
在这个类中我们主要做了以下修改:
1.在addUser里传进来的参数是一个User对象,我们的列表里存的是每个人的对象,而不是以前的只一个userName了.
2.在delUser里,我们做比较的是列表里对象的userName和传进来的参数
3.getUserList方法中我们要把每个人的名字筛选出来
4.将sendUserList和sendMsgToClient封装进来,因为我们的用户对象中有Client,所以直接用this.listArray[i].client就可以调用客户端方法了.
5.在addUser和delUser后通过this.sendUserList()来发送在线列表.
通过将一些方法封装进来,我们发现main.asc的代码减少了,这是好处之一,还有一个好处在后面的教程中会讲到.
最后来看一下main.asc文件:
- load("UserList.asc");
- load("User.asc");
- application.onAppStart = function() {
- this.chatMsgArray = new Array();
- this.userList = new UserList();
- }
-
- application.onConnect = function(client, userName) {
- if(this.userList.checkOnline(userName)){
- this.rejectConnection(client,{msg:"error1"});
- return;
- }
- this.acceptConnection(client);
- var user = new User(client,userName);
- this.userList.addUser(user);
- //客户端调用方法
- client.getMsg = function(){
- return application.chatMsgArray;
- }
- client.sendMsg = function(msg){
- var chatInfo = this.userName + " : " + msg;
- application.chatMsgArray.push(chatInfo);
- application.userList.sendMsgToClient(chatInfo);
- }
- }
-
- application.onDisconnect = function(client) {
- trace("用户:"+client.userName+" 离开");
- this.userList.delUser(client.userName);
- }
-
-
- application.onAppStop = function() {
-
- }
在main.asc中减少了两个方法,并且多了一个load(”User.asc”)将User.asc载入进来
在接受用户后,新建了一个User对象 — var user = new User(client,userName);
还有一个改动就是:this.rejectConnection(client,{msg:”error1″});
我们在用户已经列表中拒绝用户加了一个参数,当你有不同的拒绝信息时,这个参数会起很大的作用
客户端代码也要做相应的修改:
- 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;
-
- 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;
- nc=new NetConnection();
- nc.addEventListener (NetStatusEvent.NET_STATUS,netStatusHandler);
- nc.client = this;
- nc.connect (rtmpUrl,userName);
-
- }else{
- msg.text = "请输入用户名";
- }
-
- }
-
- private function into():void{
- 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);
- }
-
- private function netStatusHandler(event:NetStatusEvent):void{
- trace(event.info.code);
- switch (event.info.code) {
- case "NetConnection.Connect.Success" :
- trace("连接成功!");
- into();
- nc.call("getMsg",new Responder(getMsgResult,getMsgFault))
- break;
- case "NetConnection.Connect.Rejected" :
- trace("连接被拒绝!:"+event.info.application.msg);
- if(event.info.application.msg == "error1"){
- msg.text = "用户已在列表中";
- }
- break;
- case "NetConnection.Connect.Failed" :
- trace("连接失败!");
- break;
- case "NetConnection.Connect.Closed" :
- trace("连接关闭!");
- break;
- }
- }
-
- private function getMsgResult(re:Array):void{
- var s:String="";
- var len:Number = re.length;
- for(var i=0;i<len;i++){
- s += re[i]+"\n";
- }
- 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+"\n");
- }
-
- public function getUserList(list:Array):void{
- userList.dataProvider = new DataProvider(list);
- }
-
- public function close():void{
-
- }
- }
-
- }
代码比较简单,不用多讲解了,发布看一下效果,效果跟前几节还是一样,只是多了一个”用户已在列表中的提示”
下节继续.
(本教程如需转载请注明出处!)