先来看客户端fla的构成:
第一帧:登录界面
第一帧的代码:
01 |
import flash.events.MouseEvent; |
02 |
import com.adobe.utils.StringUtil; |
07 |
var userName: String = "" ; |
11 |
btnLogin.addEventListener(MouseEvent.CLICK,btnLoginClick); |
13 |
function btnLoginClick(e:MouseEvent): void { |
14 |
txtUserName.text = StringUtil.trim(txtUserName.text); |
15 |
this .userName = txtUserName.text; |
16 |
if ( this .userName.length<= 0 ){ |
17 |
Alert.show( "请输入用户名!" , null , 0xefefef , 0x000000 ); |
第二帧:聊天的主界面
代码:
01 |
import flash.net.NetConnection; |
02 |
import flash.events.MouseEvent; |
03 |
import flash.events.NetStatusEvent; |
04 |
import flash.events.KeyboardEvent; |
06 |
import flash.ui.Keyboard; |
12 |
function init(): void { |
13 |
nc = new NetConnection(); |
14 |
nc.client= new Object (); |
16 |
nc.client.showmsg = function (str: String ): void |
18 |
txtMsg.appendText(str + "\n" ); |
21 |
nc.addEventListener(NetStatusEvent.NET_STATUS,connHandler); |
23 |
updateMsg( "正在连接服务器..." ); |
24 |
btnSend.addEventListener(MouseEvent.CLICK,btnSendClick); |
26 |
txtSend.addEventListener(KeyboardEvent.KEY_DOWN,txtSendKeyDown); |
30 |
function txtSendKeyDown(e:KeyboardEvent): void { |
31 |
if (e.keyCode == Keyboard.ENTER) { |
36 |
function btnSendClick(e:MouseEvent): void { |
37 |
txtSend.text = StringUtil.trim(txtSend.text); |
38 |
if (txtSend.text != "" ) { |
39 |
nc.call( "sendmsg" , null ,txtSend.text); |
43 |
Alert.show( "请输入要发送的内容!" , null , 0xefefef , 0x000000 ); |
47 |
function connHandler(e:NetStatusEvent) { |
48 |
switch (e.info.code) { |
49 |
case "NetConnection.Connect.Closed" : |
52 |
case "NetConnection.Connect.Failed" : |
55 |
case "NetConnection.Connect.Success" : |
56 |
updateMsg( "服务器连接成功!" ); |
58 |
case "NetConnection.Connect.Rejected" : |
59 |
updateMsg( "连接尝试没有访问应用程序的权限!" ); |
62 |
txtMsg.appendText(e.info.code + "\n" ); |
67 |
function updateMsg(msg: String ): void { |
68 |
txtMsg.appendText(msg + "\n" ); |
服务端main.asc的处理(注:main.asc保存时,貌似只能选择为utf-8编码,否则运动时客户端一直连接不上)
01 |
application.onAppStart = function () { |
06 |
application.onConnect = function (client, uName) { |
07 |
trace ( "onConnect = " +uName); |
08 |
client.UserName = uName; |
09 |
application.acceptConnection(client); |
10 |
hellomsg= "系统信息:" +client.UserName+ " 进入聊天室" ; |
11 |
application.broadcastMsg( "showmsg" ,hellomsg); |
14 |
client.sendmsg = function (msg) { |
15 |
mesg = client.UserName+ ": " +msg; |
17 |
application.broadcastMsg( "showmsg" ,mesg) |
23 |
application.onDisconnect = function (client) { |
24 |
trace ( "onDisconnect =" +client.UserName); |
25 |
hellomsg= "系统信息:" +client.UserName+ " 离开聊天室" ; |
26 |
application.broadcastMsg( "showmsg" ,hellomsg) |
28 |
application.onAppStop = function () { |
运行中的样子:
注:艾睿论坛上曾有一篇教程利用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正好充当了这个角色,省去了这一步之后,程序员只需要把注意力集中在客户端和业务逻辑上即可,开发量大大缩减。