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,如需转载请自行联系原作者

目录
相关文章
|
18天前
|
编解码
Jetson 学习笔记(十四):降低远程操控延时-修改屏幕分辨率
这篇文章是关于如何通过修改屏幕分辨率来降低Jetson Nano在远程操控时的延时。
37 3
Jetson 学习笔记(十四):降低远程操控延时-修改屏幕分辨率
|
4月前
|
存储 网络协议 Ubuntu
【Linux开发实战指南】基于UDP协议的即时聊天室:快速构建登陆、聊天与退出功能
UDP 是一种无连接的、不可靠的传输层协议,位于IP协议之上。它提供了最基本的数据传输服务,不保证数据包的顺序、可靠到达或无重复。与TCP(传输控制协议)相比,UDP具有较低的传输延迟,因为省去了建立连接和确认接收等过程,适用于对实时性要求较高、但能容忍一定数据丢失的场景,如在线视频、语音通话、DNS查询等。 链表 链表是一种动态数据结构,用于存储一系列元素(节点),每个节点包含数据字段和指向下一个节点的引用(指针)。链表分为单向链表、双向链表和循环链表等类型。与数组相比,链表在插入和删除操作上更为高效,因为它不需要移动元素,只需修改节点间的指针即可。但访问链表中的元素不如数组直接,通常需要从
248 2
|
6月前
|
Web App开发 安全 API
想开发一款带有视频通话/共享屏幕功能的产品?那WebRTC是你必须要知道的!
一名技术爱好者在研究如何为开源项目集成视频通话功能时,深入学习了WebRTC技术。WebRTC是一个API,允许浏览器和应用实现实时音视频通信,简化了之前复杂的技术挑战,如音视频处理和网络传输。该技术可用于视频通话、桌面共享、视频会议等多种场景。在WebRTC中,通过信令交换、STUN/TURN服务器和ICE框架处理网络连接和通信路径,实现点对点连接。与WebSocket不同,WebRTC专注于高质量实时通信,使用UDP协议以降低延迟。接下来的文章将分享如何实现WebRTC的视频通话功能。
|
6月前
|
并行计算 Linux 异构计算
分享一款刚开源上线3天的音乐人声分离工具!无需联网!页面化操作!
分享一款刚开源上线3天的音乐人声分离工具!无需联网!页面化操作!
|
Web App开发 开发工具 Android开发
Android平台不需要单独部署流媒体服务如何实现内网环境下一对一音视频互动
我们在做内网环境的一对一音视频互动的时候,遇到这样的技术诉求:如智能硬件场景下(比如操控智能硬件),纯内网环境,如何不要单独部署RTMP或类似流媒体服务,实现一对一音视频互动。
|
存储 网络协议 小程序
我的小工具,用C和python实现远程读卡器,远程读写消费卡片
我的小工具,用C和python实现远程读卡器,远程读写消费卡片
我的小工具,用C和python实现远程读卡器,远程读写消费卡片
|
存储 JSON 小程序
云开发(微信-小程序)笔记(十)---- 刷新中
云开发(微信-小程序)笔记(十)---- 刷新中
61 0
|
Android开发 Windows
好工具推荐系列:幕享---全平台全设备投屏共享
好工具推荐系列:幕享---全平台全设备投屏共享
402 0
|
前端开发 数据库 Python
Python实现多人在线匿名聊天的小程序
最近看到好多设计类网站,都提供了多人在线匿名聊天的小功能,感觉很有意思,于是基于python的django框架自己写了一个,支持手动实时更名,最下方提供了完整的源码.
1485 0