今天我们的讲解的是在昨天代码的功能上加上在线列表的功能,同时会去掉共享对象,用另一种方法向客户端发消息.
先看看服务端代码我们更改些什么代码:
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是返回所有的聊天信息,当用户第一次连接时,得到别人的聊天记录
在用户断开连接的时候增加了将断线用户从在线列表中清除,并且发送在线列表.
再来看看客户端代码:
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)),这句是在刚连接成功的时候得到以前用户的聊天记录.
顺便说一句,客户端代码用到了组件,所以要把这些组件放到库中才能运行,上一节也是这样的.