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

简介:
      FMS开发中,经常会使用共享对象来同步用户和存储数据。对于实现广播文字信息实现聊天的支持非常强大,还可以跟踪用户的时时动作,在开发Flash多人在线游戏中的应用也非常广阔。
 
      在使用FMS开发共享对象时需要注意,只有使用Flash Media Interactive Server或Flash Media Development Server这两个版本时才能够创建和使用远程共享对象,来实现多客户端的应用程序之间共享数据。如果是使用的Flash Media Streaming Server版FMS是不能创建远程共享对象的,只能创建本地共享对象,类似于传统Web开发中的Cookie。
 
      使用共享对象(SharedObject)来开发时时文字聊天其实是很简单的,SharedObject可以跟踪和广播消息,连接到SharedObject中的其中任何一个客户端改变了SharedObject中的数据,SharedObject就会将最新的数据广播到连接到它的所有客户端。从某种角度可以理解为远程的SharedObject是一个同步很多用户的一个网络中心。下图为官方发布的SharedObject广播消息图:
 
 
        本文是通过实现一个简单的文字聊天来介绍FMS中的远程共享对象的使用,首先在FMS中建立好应用程序名,既在FMS的安装目录下的applications下建立一文件夹,来作为共享对象应用程序使用,如下图所示:
 
 
        如上图,SharedObjectApp就是为实现聊天建立的一个FMS应用文件夹,其下的sharedobjects/_definse_为成功创建远程对象后自动生成的目录。如果你所创建的为永久性的远程共享对象,则在该目录下还将会有一个以.fso为扩展名的远程共享对象文件。
      要创建远程共享对象,首先需要连接到FMS应用,然后通过SharedObject.getRemote()方法来完成远程共享对象的创建,通过给远程共享对象添加同步事件监听,远程共享对象里的数据一但发生改变就会自动触发该事件,来实现同步数据。
 
private  function onClick(): void
{
    nc 
=   new  NetConnection();
    nc.connect(
" rtmp://192.168.1.101/SharedObjectApp " );
    nc.addEventListener(NetStatusEvent.NET_STATUS,onNetStatusHandler);
}

private  function onNetStatusHandler(evt:NetStatusEvent): void
{
    
this .panChat.title += " ( " + evt.info.code + " ) " ;
    
if (evt.info.code == " NetConnection.Connect.Success " )
    {
        
// 创建一个远程共享对象
        
// 参数:远程共享对象的名称 | 连接到的应用程序的URI | 远程共享对象是否为永久远程对象
        so  =  SharedObject.getRemote( " RemotingSO " ,nc.uri, true );  // 将生成SO.fso
        
// 远程对象(SharedObject)同步事件的监听
        so.addEventListener(SyncEvent.SYNC,onSyncHandler);
        
// 远程共享对象连接到服务器
        so.connect(nc);
    }
}
 
       上面代码块实现了连接到FMS应用,成功连接后便创建远程共享对象(RemotingSO),同时还为远程共享对象添加了同步事件监听,通过onSyncHandler方法来处理事件。
      在继续实现聊天功能前,我们需要编写一个通用方法,该方法提供将一个数组里的数据转移到另一个数组,如下代码块:
 
private  function convertArrayCollection(arrNew:ArrayCollection,arrOld:ArrayCollection): void
{
     arrNew.removeAll();
  
     
for (var i: int = 0 ;i < arrOld.length ;i ++ )
     {
          arrNew.addItemAt(arrOld.getItemAt(i),i);
     }
}
 
      下面我们通过发送消息的流程开始,首先是发送消息,通过自定义Message类来封装消息内容:
 1  package flex.VO
 2  {
 3       public   class  Message
 4      {
 5           public  var NickName:String;  //用户呢称
 6           public  var Context:String;    //消息内容
 7          
 8           public  function Message()
 9          {
10          }
11      }
12  }
 
      在发送消息的时候,通过此Message类来封装发送消息的数据,然后将其发布到FMS中的远程共享对象,更新远程共享对象中的数据。
private  function onSend(): void
{
    var tempCollection:ArrayCollection 
=   new  ArrayCollection();
    
if (so.data.msgCollection  !=   null )
    {
        convertArrayCollection(tempCollection,so.data.msgCollection 
as  ArrayCollection);
    }
    
    var msg:Message 
=   new  Message();
    msg.NickName 
=   this .txtUser.text;
    msg.Context 
=   this .txtMessage.text;
    tempCollection.addItem(msg);
    //更新远程共享对象中的属性值
    so.setProperty(
" msgCollection " ,tempCollection);
    
    
this .txtMessage.text = "" ;
}
 
      实现了发送消息(将消息添加到远程共享对象并更新远程共享对象的属性值),如果有多个客户端连接到该远程共享对象,这时就回触发远程共享对象的同步事件,通过同步事件处理方法就可以将远程共享对象中的数据同步到客户端。如下代码块:
 
private  function onSyncHandler(evt:SyncEvent): void
{
    
if (so.data.msgCollection != null )
    {
        var tempCollection:ArrayCollection 
=   new  ArrayCollection();
        convertArrayCollection(tempCollection,so.data.msgCollection 
as  ArrayCollection);
        
        
this .msgText.text = "" ;
        
for (var index: int = 0 ;index < tempCollection.length;index ++ )
        {
            var message:Object 
=  tempCollection.getItemAt(index);
            var displayMessage:String 
=  message.NickName + " 说: " + message.Context;
            
this .msgText.text  +=  displayMessage  +   " \n " ;
        }
    }
}
 
      如上便完成了整个文字聊天的功能开发,主要应用到的技术点就是通过远程共享对象来同步用户数据。下面为完整的Flex端代码:
<? xml version = " 1.0 "  encoding = " utf-8 " ?>
< mx:Application xmlns:mx = " http://www.adobe.com/2006/mxml "  layout = " absolute "  fontSize = " 12 " >
    
< mx:Script >
        
<! [CDATA[
            import mx.controls.Alert;
            import mx.collections.ArrayCollection;
            import flex.VO.Message;
            
            
private  var nc:NetConnection;
            
private  var so:SharedObject;
            
            
private  function onClick(): void
            
{
                nc 
= new NetConnection();
                nc.connect(
"rtmp://192.168.1.101/SharedObjectApp");
                nc.addEventListener(NetStatusEvent.NET_STATUS,onNetStatusHandler);
            }

            
            
private  function onNetStatusHandler(evt:NetStatusEvent): void
            
{
                
this.panChat.title+="("+evt.info.code+")";
                
if(evt.info.code=="NetConnection.Connect.Success")
                
{
                    
//创建一个远程共享对象
                    
//参数:远程共享对象的名称 | 连接到的应用程序的URI | 远程共享对象是否为永久远程对象
                    so = SharedObject.getRemote("RemotingSO",nc.uri,true); //将生成SO.fso
                    
//远程对象(SharedObject)同步事件的监听
                    so.addEventListener(SyncEvent.SYNC,onSyncHandler);
                    
//远程共享对象连接到服务器
                    so.connect(nc);
                }

            }

            
            
private  function onSyncHandler(evt:SyncEvent): void
            
{
                
if(so.data.msgCollection!=null)
                
{
                    var tempCollection:ArrayCollection 
= new ArrayCollection();
                    convertArrayCollection(tempCollection,so.data.msgCollection 
as ArrayCollection);
                    
                    
this.msgText.text="";
                    
for(var index:int=0;index<tempCollection.length;index++)
                    
{
                        var message:Object 
= tempCollection.getItemAt(index);
                        var displayMessage:String 
= message.NickName+"说:"+message.Context;
                        
this.msgText.text += displayMessage + "\n";
                    }

                }

            }

            
            
private  function onSend(): void
            
{
                var tempCollection:ArrayCollection 
= new ArrayCollection();
                
if(so.data.msgCollection != null)
                
{
                    convertArrayCollection(tempCollection,so.data.msgCollection 
as ArrayCollection);
                }

                
                var msg:Message 
= new Message();
                msg.NickName 
= this.txtUser.text;
                msg.Context 
= this.txtMessage.text;
                tempCollection.addItem(msg);
                
//更新远程共享对象中的属性值
                so.setProperty("msgCollection",tempCollection);
                
                
this.txtMessage.text="";
            }

            
            
private  function convertArrayCollection(arrNew:ArrayCollection,arrOld:ArrayCollection): void
            
{
                 arrNew.removeAll();
              
                 
for(var i:int=0;i<arrOld.length ;i++)
                 
{
                      arrNew.addItemAt(arrOld.getItemAt(i),i);
                 }

            }

        ]]
>
    
</ mx:Script >
    
< mx:Panel x = " 22 "  y = " 22 "  width = " 482 "  height = " 260 "  layout = " absolute "   id = " panChat "
        title
= " 文字聊天 " >
        
< mx:TextArea x = " 0 "  y = " 0 "  width = " 100% "  height = " 100% "  backgroundColor = " #FCDADA "  id = " msgText " />
        
< mx:ControlBar >
            
< mx:TextInput width = " 53 "  id = " txtUser " />
            
< mx:Label text = " 说: " />
            
< mx:TextInput width = " 195 "  id = " txtMessage " />
            
< mx:Button label = " Send "  click = " onSend() " />
            
< mx:Button label = " Connection "  fontWeight = " normal "  click = " onClick() " />
        
</ mx:ControlBar >
    
</ mx:Panel >
    
</ mx:Application >
 
 
 
 
 
       如上图,在FMS应用目录下创建了一后缀为.fso的文件,这就是永久性的远程共享对象文件名。在使用远程共享的时候,根据实际需求来确定是否使用永久性的远程共享对象,一般做聊天应用我个人建议使用临时远程共享对象(不生成.fso文件),要存储聊天记录可以通过其他方式来保存。
      详细大家可以查看官方提供的文档,在FMS的安装目录下就有,我的是D:\Adobe\Flash Media Server 3\documentation\flashmediaserver_AS3LR\index.html
 
      本文就介绍于此,如文中有什么问题,请大家拍砖指正。 本文示例源代码下载




本文转自 beniao 51CTO博客,原文链接:http://blog.51cto.com/beniao/156206,如需转载请自行联系原作者

目录
相关文章
|
2天前
|
存储 缓存 前端开发
Web端IM聊天消息该不该用浏览器本地存储?一文即懂!
鉴于目前浏览器技术的进步(主要是HTML5的普及),在Web网页端IM聊天应用的技术选型阶段,很多开发者都会纠结到底该不该像原生移动端IM那样将聊天记录缓存在浏览器的本地,还是像传统Web端即时通讯那样继续存储在服务端?本文将为你简洁明了地讲清楚浏览器本地存储技术(Web Storage),然后你就知道到底该怎么选择了。
11 1
|
4月前
|
存储 网络协议 Ubuntu
【Linux开发实战指南】基于UDP协议的即时聊天室:快速构建登陆、聊天与退出功能
UDP 是一种无连接的、不可靠的传输层协议,位于IP协议之上。它提供了最基本的数据传输服务,不保证数据包的顺序、可靠到达或无重复。与TCP(传输控制协议)相比,UDP具有较低的传输延迟,因为省去了建立连接和确认接收等过程,适用于对实时性要求较高、但能容忍一定数据丢失的场景,如在线视频、语音通话、DNS查询等。 链表 链表是一种动态数据结构,用于存储一系列元素(节点),每个节点包含数据字段和指向下一个节点的引用(指针)。链表分为单向链表、双向链表和循环链表等类型。与数组相比,链表在插入和删除操作上更为高效,因为它不需要移动元素,只需修改节点间的指针即可。但访问链表中的元素不如数组直接,通常需要从
276 2
|
6月前
|
并行计算 Linux 异构计算
分享一款刚开源上线3天的音乐人声分离工具!无需联网!页面化操作!
分享一款刚开源上线3天的音乐人声分离工具!无需联网!页面化操作!
101 1
|
Web App开发 开发工具 Android开发
Android平台不需要单独部署流媒体服务如何实现内网环境下一对一音视频互动
我们在做内网环境的一对一音视频互动的时候,遇到这样的技术诉求:如智能硬件场景下(比如操控智能硬件),纯内网环境,如何不要单独部署RTMP或类似流媒体服务,实现一对一音视频互动。
|
存储 网络协议 小程序
我的小工具,用C和python实现远程读卡器,远程读写消费卡片
我的小工具,用C和python实现远程读卡器,远程读写消费卡片
我的小工具,用C和python实现远程读卡器,远程读写消费卡片
|
Web App开发 编解码 移动开发
探秘移动端网页调用摄像头的两种方式
PC 端网页调用摄像头的场景想必大家并不陌生,打开一个网址,开启摄像头开始笔试/视频聊天/直播等。 而在移动端网页调用摄像头的场景你见得多吗?我想答案应该是不多吧(在下见识浅薄)。
|
SQL Python Windows
结合pyqt5开发办公文档一键转换软件,以后再也不用开会员转文件了
自动化办公能大量提高我们的工作效率,而且利用自动化办公能够有效避免枯燥无味的机械操作,把手腾出来做其他更有意义的事.现在加上Python能够提供大量开源的自动化办公的库,能够快速实现很多需要开通vip才能使用的功能.比如文档之间格式的转换.比如,我要制作邀请函.如果office掌握不好.一张一张制作也是一件很痛苦的事,利用Python就能够实现批量生成邀请函.除了自动化办公,python还能够实现很多有趣的功能,感兴趣的可以自行深入了解,接下来本文手把手带你实现文档转换功能以及封装到pyqt5,并打包成exe可执行文件
146 0
|
Android开发 Windows
好工具推荐系列:幕享---全平台全设备投屏共享
好工具推荐系列:幕享---全平台全设备投屏共享
408 0
|
数据库 Android开发 数据安全/隐私保护
更换手机设备时如何同步迁移便签内容?
更换手机设备时如何同步迁移便签内容? 当更换同品牌手机时,通常可利用手机云服务功能将便签内容进行备份,在新手机上登录云空间恢复便签数据完成内容迁移。
4048 0
下一篇
无影云桌面