Flash/Flex学习笔记(53):利用FMS快速创建一个文本聊天室

先来看客户端fla的构成:

第一帧:登录界面

第一帧的代码:

import flash.events.MouseEvent;
import com.adobe.utils.StringUtil;
import utils.Alert;

stop();

var userName:String="";

Alert.init(stage);

btnLogin.addEventListener(MouseEvent.CLICK,btnLoginClick);

function btnLoginClick(e:MouseEvent):void{
	txtUserName.text = StringUtil.trim(txtUserName.text);
	this.userName = txtUserName.text;
	if (this.userName.length<=0){
		Alert.show("请输入用户名!",null,0xefefef,0x000000);
	}
	else{
		gotoAndPlay(2);
	}
}

第二帧:聊天的主界面

代码:

import flash.net.NetConnection;
import flash.events.MouseEvent;
import flash.events.NetStatusEvent;
import flash.events.KeyboardEvent;
import utils.Alert;
import flash.ui.Keyboard;

stop();

var nc:NetConnection;

function init():void {
	nc = new NetConnection();
	nc.client=new Object();
	//定义供服务端广播消息时需要的客户端函数(结合main.asc查看)
	nc.client.showmsg = function (str:String):void
	{
	txtMsg.appendText(str + "\n");
	};

	nc.addEventListener(NetStatusEvent.NET_STATUS,connHandler);
	nc.connect("rtmp://localhost/chat",userName);//注:这里的userName是在第一帧定义的
	updateMsg("正在连接服务器...");
	btnSend.addEventListener(MouseEvent.CLICK,btnSendClick);

	txtSend.addEventListener(KeyboardEvent.KEY_DOWN,txtSendKeyDown);

}

function txtSendKeyDown(e:KeyboardEvent):void {
	if (e.keyCode == Keyboard.ENTER) {
		btnSendClick(null);
	}
}

function btnSendClick(e:MouseEvent):void {
	txtSend.text = StringUtil.trim(txtSend.text);
	if (txtSend.text != "") {
		nc.call("sendmsg",null,txtSend.text);
		txtSend.text = "";
	}
	else {
		Alert.show("请输入要发送的内容!",null,0xefefef,0x000000);
	}
}

function connHandler(e:NetStatusEvent) {
	switch (e.info.code) {
		case "NetConnection.Connect.Closed" :
			updateMsg("成功关闭连接!");
			break;
		case "NetConnection.Connect.Failed" :
			updateMsg("连接尝试失败!");
			break;
		case "NetConnection.Connect.Success" :
			updateMsg("服务器连接成功!");
			break;
		case "NetConnection.Connect.Rejected" :
			updateMsg("连接尝试没有访问应用程序的权限!");
			break;
		default :
			txtMsg.appendText(e.info.code + "\n");
			break;
	}
}

function updateMsg(msg:String):void {
	txtMsg.appendText(msg + "\n");
}

init();

服务端main.asc的处理(注:main.asc保存时,貌似只能选择为utf-8编码,否则运动时客户端一直连接不上)

application.onAppStart = function() {
	trace("onAppStart");
};

//新客户端连接时触发
application.onConnect = function(client, uName) {
	trace("onConnect = "+uName);
	client.UserName = uName;
	application.acceptConnection(client);//允许客户登录,如果要对客户身份做验证,在此扩展即可
	hellomsg="系统信息:"+client.UserName+" 进入聊天室";
	application.broadcastMsg("showmsg",hellomsg);//调用所有client的showmsg方法,并传递参数hellomsg(客户端的代码中,必须有对应的showmsg函数)

	//定义服务端的sendmsg方法,以便客户端能调用
	client.sendmsg = function(msg) {
		mesg = client.UserName+": "+msg;
		//每次client调用本方法后,服务器同步广播到所有client
		application.broadcastMsg("showmsg",mesg)
	};

};

//有客户端断开连接时触发
application.onDisconnect = function(client) {
	trace("onDisconnect ="+client.UserName);
	hellomsg="系统信息:"+client.UserName+" 离开聊天室";
	application.broadcastMsg("showmsg",hellomsg)
};
application.onAppStop = function() {
	trace("onAppStop");
};

运行中的样子:

注:艾睿论坛上曾有一篇教程利用FMS的远程共享对象来创建聊天室,远程对象在编码上也许更简单,不过个人感觉性能不太理想(因为对于共享对象的广播是FMS自动的,完全不受控制,不管客户端想不想接收消息,都会被动接收消息),本文演示的是另一种常见做法(服务端可以有选择性的仅向某些Client发送消息),而且网上也有很多相关文章,只不过要么是收费的,要么是基于AS2.0的,今天用AS3.0整理出来,于已方便、与人方便。

源代码下载:http://cid-2959920b8267aaca.skydrive.live.com/self.aspx/Flash/FMSTxtChatBasicDemo.rar

 

后话:这个跟silverlight做的聊天室(基于scoket或wcf双工通讯)有什么不同呢? 答:silverlight做聊天室应用,往往需要开发者自己做一个(scoket) server端,而adobe的fms正好充当了这个角色,省去了这一步之后,程序员只需要把注意力集中在客户端和业务逻辑上即可,开发量大大缩减。

时间: 2010-05-24

Flash/Flex学习笔记(53):利用FMS快速创建一个文本聊天室的相关文章

Flash/Flex学习笔记(15):FMS 3.5之远程共享对象(Remote Shared Object)

FMS中的"远程共享对象"可以让多个Client端的flash应用共享同一个全局对象,并且当客户端中的任何一个改变该对象时,系统会自动将该对象回发到FMS服务器,同时FMS服务器也会将该对象重新广播到所有客户端.   说得更通俗一点:如果二个机器上浏览这种flash应用,在一台机器上所做的操作,将会在另一台机器同步体现出来.   这个能干嘛? 电子教室(比如老师在一台机器上演示教学,其它所有机器上能同步刷新),互动游戏(比如:游戏中的情侣可以在异地同时装修自己的房子),需要在服务端保存

Flash/Flex学习笔记(10):FMS 3.5之Hello World!

Adobe的FMS真的是一个倍儿牛叉的技术!(至少Silverlight在"实时广播"方面目前还没有任何能超越FMS的迹象) 曾经盛极一时的tudou,ku6,第一视频...等一大堆视频分享类网站,几乎都使用的是Adobe的FMS技术. 今天先来做一个最简单的Hello World(例子出自FMS的官方文档) 1.先创建一个FMS应用HelloWorld 进入FMS的默认安装目录: C:\Program Files\Adobe\Flash Media Server 3.5\applic

Flash/Flex学习笔记(12):FMS 3.5之如何做视频实时直播

硬件条件:一个摄像头 + 一台FMS服务器即可 原理:摄像头实时采集视频源,然后推送到FMS服务器,其它客户从FMS上获取视频流. 需要做二个fla,一个用于向FMS服务端推送视频源(即发送端),一个用于从FMS服务器获取并播放视频(即接收端) Server.fla关键代码: var cam:Camera; var vod:Video; var intervalId:uint; var intelvalTimes:uint=0; var isWorked=false; var nc:NetCon

Flash/Flex学习笔记(36):自己动手实现一个滑块控件(JimmySilder)

先看最终的演示: 滑块条的应用实在太广泛了:mp3播放器中声量的大小控制,视频播放时的画面亮度调节,阅读新闻时字体大小的实时调整,对象的大小互动控制... 分析: 1.任何一个滑块条控件的UI部分,基本上可以分为:背景滑块条 + 滑块按钮 二个部分 所以我分成了三部分: JimmySilderBar(背景条),JimmySilderButton(拖动钮),JimmySilder(真正的滑动控件,将前二个组合在一起),为了重用,这三个部分都做成MovieClip元件放在库里,这样以后要换风格或颜色

Flash/Flex学习笔记(37):不用系统组件(纯AS3)的视频播放器--只有8.82K

以前为了赶项目,利用系统组件制作过一款视频播放器(见Flash/Flex学习笔记(6):制作基于xml数据源的flv视频播放器),但是系统组件实在是太大了,最终生成的swf居然有103K,随着AS3的深入学习,昨天又弄了一个只用AS3的播放器,最终只有8.82K,呵呵,这肥减得那是相当厉害. 用到了上一篇(Flash/Flex学习笔记(35):自己动手实现一个滑块控件(JimmySilder))里自己写的的滑块控件,主要代码如下(关键是NetConnection与NetStream对象的使用):

Flash/Flex学习笔记(46):正向运动学

所谓"正向运动学"通俗点讲就是把几个连接部件的一端固定起来,另一个端可以自由(向前/向外)运动.比如人的行走,单个下肢可以理解为脚连接小腿,小腿连接大腿,大腿连接腰.行走的过程,相当于二条腿相对固定于腰部,大腿运动驱动小腿,小腿又驱动脚,从而带动整个连接系统的一系列运动. 先来一个基本的关节类Segment:(就是一个圆角矩形+二个小圆圈) package { import flash.display.Sprite; import flash.geom.Point; public cl

Flash/Flex学习笔记(25):摩擦力与屏幕环绕

摩擦力: 假如一个物体在某个方向上沿直线运行,摩擦力会使该方向上的速度越来越小,直到停止. 上图示意了该过程,物体以moveAngle角度正向运动,最终的速度speed矢量为vx矢量与vy矢量的矢量和,在每个单位时间内的位移即Speed矢量的大小,分解到x,y轴后,即为vx与vy:加入摩擦力后,speed矢量每单位时间将减少Friction值,也就是视觉上的越来越慢. var ball:Ball = new Ball(10); ball.x = stage.stageWidth/2; ball.

Flash/Flex学习笔记(24):粒子效果

粒子爆炸: 仍然要用到以前的小球类,不过稍加改造 package { import flash.display.Sprite; //小球 类 public class Ball extends Sprite { public var radius:uint;//半径 public var color:uint;//颜色 public var vx:Number=0;//x轴速度 public var vy:Number=0;//y轴速度 public function Ball(r:Number

Flash/Flex学习笔记(30):不用startDrag和stopDrag的对象拖动

对于从Sprite类继承来的对象,要实现拖放当然是Flash/Flex学习笔记(13):对象拖动(startDrag/stopDrag) 里讲的方法最方便,但是对于不是从Sprite类继承得来的对象,这startDrag/stopDrag是不能用的,这时候只能采用最通常用做法:利用Mouse_Down,Mouse_UP,Mouse_Move事件来处理 注意:对象的Mouse_Move事件,只有当鼠标在对象上时才能被监听,如果用户鼠标移动过快,超出了对象的范围,该事件就不起作用了,所以监听Mous