在上一节中,我们将一些方法进一步封装到了UserList类中 了,这样做是有很多好处的,以前经常有朋友问我像聊天室怎么做成多房间,像斗地主怎么做成多个桌子在打,其实原理都是一样的,我们只需要对 UserList类做一些改造,就可以达到这个功能了,首先把类的名字改成ChatRoom,这样更好认一些,先看ChatRoom.asc,是由 UserList.asc改造而来的:
- function ChatRoom(id){
- this.id = id;
- this.listArray = [];
- this.chatMsgArray = [];
- }
-
- ChatRoom.prototype.addUser = function(user){
- this.listArray.push(user);
- this.sendUserList();
- }
-
- ChatRoom.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();
- }
-
- ChatRoom.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;
- }
-
- ChatRoom.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;
- }
-
- ChatRoom.prototype.sendUserList = function(){
- sendAllRoomNum(this.id,this.listArray.length);
- var len = this.listArray.length;
- for(var i=0;i<len;i++){
- this.listArray[i].client.call("getUserList",null,this.getUserList());
- }
- }
-
- ChatRoom.prototype.sendMsgToClient = function(chatInfo){
- trace("sendMsgToClient:"+chatInfo);
- this.chatMsgArray.push(chatInfo);
- var len = this.listArray.length;
- for(var i=0;i<len;i++){
- this.listArray[i].client.call("getMsgInfo",null,chatInfo);
- }
- }
来看看ChatRoom类和UserList类有什么区别:
1.在构造中增加了this.id = id,这里的id表示每个房间的编号,这样可以区别当前是哪个房间.
2.this.chatMsgArray,存储聊天信息的数组,之前是放在main.asc里面的,因为之前只有一个房间,而现在有多个房间,所以每个房间都应该有一个自己的聊天信息列表.
main.asc文件也做了相应的修改:
- load("ChatRoom.asc");
- load("User.asc");
- application.onAppStart = function() {
- this.roomArray = [];
- this.roomUserNum = [];
- var roomLen = 3;
- for(var i=0;i< roomLen ;i++){
- this.roomArray.push(new ChatRoom(i+1));
- this.roomUserNum.push(0);
- }
- }
-
- application.onConnect = function(client) {
- this.acceptConnection(client);
- //客户端调用方法
- client.addRoom = function(userName,roomid){
- trace(userName,roomid);
- var isOnline = application.roomArray[roomid - 1].checkOnline(userName);
- if(!isOnline){
- var user = new User(this,userName,roomid);
- application.roomArray[roomid - 1].addUser(user);
- return true;
- }else{
- return false;
- }
- }
- client.getMsg = function(roomid){
- return application.roomArray[roomid - 1].chatMsgArray;
- }
- client.sendMsg = function(roomid,msg){
- var chatInfo = this.userName + " : " + msg;
- application.roomArray[roomid - 1].sendMsgToClient(chatInfo);
- }
- client.getAllUserNum = function(){
- return application.roomUserNum;
- }
- }
-
- application.onDisconnect = function(client) {
- trace("用户:"+client.userName+" 离开 "+client.roomid);
- this.roomArray[client.roomid - 1].delUser(client.userName);
- }
-
-
- application.onAppStop = function() {
-
- }
-
- function sendAllRoomNum(roomid,num){
- application.roomUserNum[roomid - 1] = num;
- var len = application.clients.length;
- for(var i= 0;i<len ;i++){
- application.clients[i].call("getAllRoomNum",null,application.roomUserNum);
- }
- }
在这个类中我们主要做了以下修改:
1.this.roomArray,用来存储每个房间实例的数组;this.roomUserNum,所有房间当前在线人数的数组;在这里我定义了三个房间,这个可以任意设定.
2.在客户端连接进来时,直接接受客户端连接,不做判断,把判断改在addRoom完成.
3.在客户端发过来的消息中,多加了个参数,就是roomid,用于区别是哪个房间发来的消息,然后根据roomid来判断调用哪个房间实例的方法.
4.增加sendAllRoomNum方法,用于发送实时的所有房间人数,供客户端的大厅显示,正常大厅的可以实时看到人数变化.
客户端代码也要做相应的修改:
- 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/chatLobby";
- 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;
-
- private var allRoomNum :Array = new Array();
- private var roomBtnArray:Array = new Array();
-
- private var onlineArray:Array = new Array();
-
- private var currentRoomid:Number;
-
- 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);
-
- }else{
- msg.text = "请输入用户名";
- }
-
- }
-
- private function netStatusHandler(event:NetStatusEvent):void{
- trace(event.info.code);
- switch (event.info.code) {
- case "NetConnection.Connect.Success" :
- trace("连接成功!");
- nc.call("getAllUserNum",new Responder(getAllUserNumResult,getAllUserNumFault))
- break;
- case "NetConnection.Connect.Rejected" :
- trace("连接被拒绝!");
- break;
- case "NetConnection.Connect.Failed" :
- trace("连接失败!");
- break;
- case "NetConnection.Connect.Closed" :
- trace("连接关闭!");
- break;
- }
- }
-
- private function getAllUserNumResult(re:Array):void{
- trace("getAllUserNumResult:"+re);
- removeChild(userNameInput);
- removeChild(enterBtn);
- removeChild(msg);
- allRoomNum = re;
- var xpos = 100;
- var ypos = 200;
- var num = 150;
- var len = allRoomNum.length;
- for(var i=0 ;i<len;i++){
- var btn:Button = new Button();
- btn.x = xpos;
- btn.y = ypos;
- xpos += num;
- btn.label = (i+1) + "号房间("+allRoomNum[i]+"/"+(i+1) * 10 + ")";
- addChild(btn);
- btn.addEventListener(MouseEvent.CLICK,roomBtnHandler);
- roomBtnArray.push(btn);
- }
- }
-
-
- private function getAllUserNumFault(fe:*):void{
- trace(fe);
- }
-
- private function intoRoom():void{
- var len = roomBtnArray.length;
- for(var i=0;i<len;i++){
- removeChild(roomBtnArray[i]);
- }
- roomBtnArray = [];
- 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);
- userList.dataProvider = new DataProvider(onlineArray);
- nc.call("getMsg",new Responder(getMsgResult,getMsgFault),currentRoomid);
- }
-
- private function getMsgResult(re:*):void{
- var msg:String = "";
- var len:Number = re.length;
- for(var i=0;i<len;i++){
- msg += re[i]+"\n";
- }
- textArea.text = msg;
- }
-
- private function getMsgFault(fe:*):void{
-
- }
-
- private function roomBtnHandler(event:MouseEvent):void{
- var roomid = Number(event.currentTarget.label.substr(0,1));
- if(allRoomNum[roomid - 1] == roomid * 10){
- event.currentTarget.label = "此房间已满";
- }else{
- nc.call("addRoom",new Responder(addRoomResult,addRoomFault),userName,roomid);
- currentRoomid = roomid;
- }
- }
-
- private function addRoomResult(re:*):void{
- trace(re);
- if(re){
- intoRoom();
- }
- }
-
- private function addRoomFault(fe:*):void{
-
- }
-
- private function sendMsg (e:MouseEvent):void{
- nc.call("sendMsg",null,currentRoomid,textInput.text);
- textInput.text = "";
- }
-
- public function getMsgInfo(msg:String):void{
- textArea.appendText(msg+"\n");
- }
-
- public function getUserList(list:Array):void{
- trace("getuserList:"+list);
- onlineArray = list;
- if(userList){
- userList.dataProvider = new DataProvider(onlineArray);
- }
- }
-
- public function getAllRoomNum(array:Array):void{
- allRoomNum = array;
- var len = roomBtnArray.length;
- if(len > 0){
- for(var i=0;i<len;i++){
- roomBtnArray[i].label = (i+1) + "号房间("+allRoomNum[i]+"/"+(i+1) * 10 + ")";
- }
- }
- }
-
- public function close():void{
-
- }
- }
-
- }
客户端增加一个大厅,然后再进房间,客户端的代码我就不详细讲解了,因为这不是一个讲AS3的教程,会一些AS3的朋友应该都看得懂,如果不懂,可 以先看一下我写的关于AS3的教程,这个客户端代码写得有点乱,只是完成了功能,FMS的教程写完后,我准备写一些关了MVC框架的使用教程,像 cairngorm和pureMVC,到时会将代码处理得更好些.
下节继续.
(本教程如需转载请注明出处!)