FluorineFx:基于RSO(远程共享对象)的文本聊天室

在前一篇“FluorineFx:远程共享对象(Remote SharedObjects)”里,已经大致知道了在FluorineFX中如何使用RSO,这一篇将利用RSO完成一个简单的文本聊天室。

原理:

RSO对象中,创建二个属性:msg和online,分别用来保存"用户每次发送的聊天内容"以及"在线用户列表"

运行截图:

服务端代码:

using System.Collections;
using FluorineFx.Messaging.Api;
using FluorineFx.Messaging.Api.SO;

namespace _03_RSO_Chat
{
    public class ChatSecurityHandler : ISharedObjectSecurity
    {
        #region ISharedObjectSecurity Members

        //是否允许连接
        public bool IsConnectionAllowed(ISharedObject so)
        {
            return true;
        }

        //是否允许创建rso对象(下面的代码仅允许创建名为chat的rso对象)
        public bool IsCreationAllowed(IScope scope, string name, bool persistent)
        {
            if (name=="chat")
            {
                return false;
            }
            else
            {
                return true;
            }
        }

        //是否允许删除
        public bool IsDeleteAllowed(ISharedObject so, string key)
        {
            return false;
        }

        //是否允许rso对象向服务端send指定回调方法(下面的代码仅允许发送名为drop的回调方法)
        public bool IsSendAllowed(ISharedObject so, string message, IList arguments)
        {
            return true;
        }

        //rso对象的属性是否可写
        public bool IsWriteAllowed(ISharedObject so, string key, object value)
        {
            return true;
        }

        #endregion
    }
}

ChatApplication.cs

using FluorineFx.Messaging.Adapter;
using FluorineFx.Messaging.Api;
using FluorineFx.Messaging.Api.SO;
using System.Collections;
using System;
using System.Collections.Generic;
using System.Linq;

namespace _03_RSO_Chat
{
    public class ChatApplication : ApplicationAdapter
    {
        public override bool AppStart(IScope application)
        {
            RegisterSharedObjectSecurity(new ChatSecurityHandler());//注册刚才定义的安全处理Handler
            return base.AppStart(application);
        }

        /// <summary>
        /// 每当有新客户端连接到服务器时,该方法会被触发
        /// </summary>
        /// <param name="connection"></param>
        /// <param name="parameters"></param>
        /// <returns></returns>
        public override bool AppConnect(IConnection connection, object[] parameters)
        {
            string userName = string.Empty, passWord = string.Empty;

            if (parameters.Length >= 2)
            {
                userName = parameters[0].ToString();//第一个参数当作用户名
                passWord = parameters[1].ToString();//第二个参数当作密码
            }

            if (string.IsNullOrEmpty(userName))
            {
                userName = "游客" + (new System.Random()).Next(0, 9999).ToString();
            }

            //if (userName == "jimmy.yang" && passWord == "123456")//安全性校验
            //{
            if (base.AppConnect(connection, parameters))
            {
                //获取共享对象(position)
                ISharedObject iso = GetSharedObject(connection.Scope, "chat");
                if (iso == null)
                {
                    //创建共享对象
                    CreateSharedObject(connection.Scope, "chat", true);
                    iso = GetSharedObject(connection.Scope, "chat");
                }

                //更新聊天记录
                iso.SetAttribute("msg", "<font color='#0000ff'>系统:</font><font color='#ff0000'>" + userName + "</font> 进入聊天室!</font>");

                //处理在线名单
                string[] online = iso.GetAttribute("online") as string[];
                List<string> lst = new List<string>();
                if (online == null)
                {
                    lst.Add(userName);
                }
                else
                {
                    lst.AddRange(online);
                }
                if (!lst.Contains(userName))
                {
                    lst.Add(userName);
                }
                iso.SetAttribute("online", lst.ToArray());

                //更新connection的userName属性(退出时会用到)
                connection.Client.SetAttribute("userName", userName);

                return true;
            }
            else
            {
                RejectClient("连接失败,请检查服务端是否运行正常!");
                return false;
            }
            //}
            //else
            //{
            //    RejectClient("用户名或密码错误");
            //    return false;
            //}
        }

        /// <summary>
        /// 每当用户断开连接时,触发此事件
        /// </summary>
        /// <param name="connection"></param>
        public override void AppDisconnect(IConnection connection)
        {
            try
            {
                string userName = connection.Client.GetAttribute("userName") as string;

                //获取共享对象(position)
                ISharedObject iso = GetSharedObject(connection.Scope, "chat");

                //发送离线通知
                iso.SetAttribute("msg", "<font color='#0000ff'>系统:</font><font color='#ff0000'>" + userName + "</font> 离开了聊天室!</font>");

                //处理在线名单
                string[] online = iso.GetAttribute("online") as string[];
                List<string> lst = new List<string>();
                if (online == null)
                {
                    lst.Add(userName);
                }
                else
                {
                    lst.AddRange(online);
                }
                if (lst.Contains(userName))
                {
                    lst.Remove(userName);
                }
                iso.SetAttribute("online", lst.ToArray());
            }
            catch { }

            base.AppDisconnect(connection);
        }
    }
}

Flash客户端代码:

package
{
	import fl.controls.Button;

	import flash.display.SimpleButton;
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.events.NetStatusEvent;
	import flash.events.SyncEvent;
	import flash.net.NetConnection;
	import flash.net.SharedObject;
	import flash.text.TextField;
	import flash.events.KeyboardEvent;
	import flash.ui.Keyboard;

	public class Chat extends Sprite
	{

		private var _btnConn:Button;
		private var _nc:NetConnection;
		private var _remoteUrl:String;
		private var _rso:SharedObject;

		private var _txtAppName:TextField;
		private var _txtContent:TextField;
		private var _txtIP:TextField;
		private var _txtOnline:TextField;
		private var _txtPassWord:TextField;
		private var _txtPort:TextField;

		private var _txtSend:TextField;
		private var _txtUserName:TextField;

		public function Chat()
		{
			this._txtIP = txtIP;
			this._txtPort = txtPort;
			this._txtAppName = txtAppName;
			this._btnConn = btnConn;
			this._txtContent = txtContent;
			this._txtOnline = txtOnline;
			this._txtUserName = txtUserName;
			this._txtPassWord = txtPassWord;
			this._txtSend = txtSend;

			this._nc=new NetConnection();
			this._nc.addEventListener(NetStatusEvent.NET_STATUS, net_status);
			//trace(this._btnLogin);
			this._btnConn.addEventListener(MouseEvent.CLICK, btnConn_Click);

			this._txtIP.text = "127.0.0.1";
			this._txtPort.text = "1935";
			this._txtUserName.text = "游客" + Math.floor(Math.random()*10000);
			this._txtPassWord.text = "123456";			

		}

		private function btnConn_Click(e:MouseEvent):void
		{
			_remoteUrl = "rtmp://" + this._txtIP.text + ":" + this._txtPort.text + "/" + this._txtAppName.text;
			//trace(this._remoteUrl);
			_nc.connect(this._remoteUrl, this._txtUserName.text, this._txtPassWord.text);
			_nc.client = this;
		}

		private function net_status(e:NetStatusEvent):void
		{
			//trace(e.info.code);
			if (e.info.code == "NetConnection.Connect.Success")
			{
				_rso = SharedObject.getRemote("chat",this._nc.uri,true);
				this._rso.addEventListener(SyncEvent.SYNC,sync_handler);
				this._rso.connect(this._nc);
				this._rso.client = this;
				this._txtContent.htmlText = "<font color='#009933'>服务端连接成功!</font><br/>";
				this._txtSend.addEventListener(KeyboardEvent.KEY_UP,txtsend_key_up);
			}
			else
			{
				this._txtContent.htmlText = "<font color='#ff0000'>服务端连接失败!</font><br/>";
			}
		}

		private function sync_handler(e:SyncEvent):void
		{
			//trace(this._rso.data.msg);
			//更新聊天记录
			if (this._rso.data.msg != undefined)
			{
				var msg:String = this._rso.data.msg + "<br/>";

				var msgTxt:String = msg.replace(/<.+?>/gi,"");
				var chatTxt:String = this._txtContent.htmlText.replace(/<.+?>/gi,"");

				//防止重复显示
				if (chatTxt.indexOf(msgTxt)==-1)
				{
					this._txtContent.htmlText +=  msg;
				}

				//trace(msg);
				//trace(this._txtContent.htmlText);

				this._txtContent.scrollV = this._txtContent.maxScrollV;
			}

			//更新在线列表
			if (this._rso.data.online != undefined)
			{
				this._txtOnline.text = (this._rso.data.online as Array).join('\n');
			}
		}

		private function txtsend_key_up(e:KeyboardEvent):void
		{
			//trace(e);
			if (this._txtSend.text.length > 0 && e.ctrlKey && e.keyCode == Keyboard.ENTER)
			{
				this._rso.setProperty("msg","<font color='#ff0000'>" + this._txtUserName.text + "</font> 说:" + this._txtSend.text);
				this._txtSend.text = "";
			}
		}
	}
}

示例源文件下载:http://cid-2959920b8267aaca.office.live.com/self.aspx/Flash/FluorineFx^_Demo^_03.rar

另:flex环境下fluorineFx的rso应用,建议大家同步参看beniao兄的文章Flex与.NET互操作(十二):FluorineFx.Net的及时通信应用(Remote Shared Objects)(三)

时间: 2024-09-18 05:22:03

FluorineFx:基于RSO(远程共享对象)的文本聊天室的相关文章

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 btnLogin

FluorineFx:远程共享对象(Remote SharedObjects)

单纯从客户端上来看,FluorineFx的RSO跟FMS中的RSO几乎没什么不同(参见Flash/Flex学习笔记(15):FMS 3.5之远程共享对象(Remote Shared Object) ),只不过FMS是Adobe的收费产品,FluorineFx是用于.Net平台的开源免费产品 . 服务端代码: 1.为了防止客户端随意连接或创建任何属性的RSO,服务端可以定义一个用于安全处理的cs文件 using System.Collections; using FluorineFx.Messag

FMS3系列(六):使用远程共享对象实现多人实时在线聊天

FMS开发中,经常会使用共享对象来同步用户和存储数据.对于实现广播文字信息实现聊天的支持非常强大,还可以跟踪用户的时时动作,在开发Flash多人在线游戏中的应用也非常广阔. 在使用FMS开发共享对象时需要注意,只有使用Flash Media Interactive Server或Flash Media Development Server这两个版本时才能够创建和使用远程共享对象,来实现多客户端的应用程序之间共享数据.如果是使用的Flash Media Streaming Server版FMS是不

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

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

与众不同 windows phone (30) - Communication(通信)之基于 Socket TCP 开发一个多人聊天室

原文:与众不同 windows phone (30) - Communication(通信)之基于 Socket TCP 开发一个多人聊天室 [索引页][源码下载] 与众不同 windows phone (30) - Communication(通信)之基于 Socket TCP 开发一个多人聊天室 作者:webabcd 介绍与众不同 windows phone 7.5 (sdk 7.1) 之通信 实例 - 基于 Socket TCP 开发一个多人聊天室 示例1.服务端ClientSocketP

与众不同 windows phone (31) - Communication(通信)之基于 Socket UDP 开发一个多人聊天室

原文:与众不同 windows phone (31) - Communication(通信)之基于 Socket UDP 开发一个多人聊天室 [索引页][源码下载] 与众不同 windows phone (31) - Communication(通信)之基于 Socket UDP 开发一个多人聊天室 作者:webabcd 介绍与众不同 windows phone 7.5 (sdk 7.1) 之通信 实例 - 基于 Socket UDP 开发一个多人聊天室 示例1.服务端Main.cs /* *

使用java基于pushlet和bootstrap实现的简单聊天室_java

这是一个简单的不能再简单的聊天室,本代码包含以下功能 1.用户注册. 2.用户登录. 3.当然还可以聊天. DBUtil.java 复制代码 代码如下: package com.hongyuan.core;   import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statemen

Flashcom中远程共享对象SharedObject的用法

object|对象 学习fcs也有差不多一个月了,感觉最有特色的东西还是SharedObject.SharedObject有不少东西,本地操作就不说了(相信很多人没接触fcs也用过);就说说远程共享对象吧.基本的应用流程是: my_nc = new NetConnection(); my_nc.connect("rtmp:/app",变量1,变量2,...); mySO=getRemote("mySO",my_nc.uri,false) mySO.connect(m

Flex与.NET互操作(十六):FluorineFx + Flex视频聊天室案例开发

本文将使用FluorineFx和Flex结合介绍一个简单的视频聊天室案例开发,希望通过此篇和大家交流FluorineFx和Flex的相关技术,同时也希 望本篇可以帮助到需要使用FluorineFx做及时应用开发的新手朋友.首先列举下本篇中所涉及到的开发环境和相关技术以及简单的需求定义: 1. Microsoft Visual Studio 2008(VS SP1)+.NET Framework 3.5(SP1) 2. FluorineFx v1.0.0.15 3. Adobe Flex Buil