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

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广播消息图:

                  SharedObject.png

      

      本文是通过实现一个简单的文字聊天来介绍FMS中的远程共享对象的使用,首先在FMS中建立好应用程序名,既在FMS的安装目录下的applications下建立一文件夹,来作为共享对象应用程序使用,如下图所示:

                  SharedObject.jpg

      如上图,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端代码:

ContractedBlock.gif ExpandedBlockStart.gif 完整的Flex端代码
None.gif<?xml version="1.0" encoding="utf-8"?>
None.gif
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" fontSize="12">
None.gif    
<mx:Script>
None.gif        
<![CDATA[
None.gif            import mx.controls.Alert;
None.gif            import mx.collections.ArrayCollection;
None.gif            import flex.VO.Message;
None.gif            
None.gif            
private var nc:NetConnection;
None.gif            
private var so:SharedObject;
None.gif            
None.gif            
private function onClick():void
ExpandedBlockStart.gifContractedBlock.gif            
dot.gif{
InBlock.gif                nc 
= new NetConnection();
InBlock.gif                nc.connect(
"rtmp://192.168.1.101/SharedObjectApp");
InBlock.gif                nc.addEventListener(NetStatusEvent.NET_STATUS,onNetStatusHandler);
ExpandedBlockEnd.gif            }

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

ExpandedBlockEnd.gif            }

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

ExpandedSubBlockEnd.gif                }

ExpandedBlockEnd.gif            }

None.gif            
None.gif            
private function onSend():void
ExpandedBlockStart.gifContractedBlock.gif            
dot.gif{
InBlock.gif                var tempCollection:ArrayCollection 
= new ArrayCollection();
InBlock.gif                
if(so.data.msgCollection != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif                
dot.gif{
InBlock.gif                    convertArrayCollection(tempCollection,so.data.msgCollection 
as ArrayCollection);
ExpandedSubBlockEnd.gif                }

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

None.gif            
None.gif            
private function convertArrayCollection(arrNew:ArrayCollection,arrOld:ArrayCollection):void
ExpandedBlockStart.gifContractedBlock.gif            
dot.gif{
InBlock.gif                 arrNew.removeAll();
InBlock.gif              
InBlock.gif                 
for(var i:int=0;i<arrOld.length ;i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif                 
dot.gif{
InBlock.gif                      arrNew.addItemAt(arrOld.getItemAt(i),i);
ExpandedSubBlockEnd.gif                 }

ExpandedBlockEnd.gif            }

None.gif        ]]
>
None.gif    
</mx:Script>
None.gif    
<mx:Panel x="22" y="22" width="482" height="260" layout="absolute"  id="panChat"
None.gif        title
="文字聊天">
None.gif        
<mx:TextArea x="0" y="0" width="100%" height="100%" backgroundColor="#FCDADA" id="msgText"/>
None.gif        
<mx:ControlBar>
None.gif            
<mx:TextInput width="53" id="txtUser"/>
None.gif            
<mx:Label text="说:"/>
None.gif            
<mx:TextInput width="195" id="txtMessage"/>
None.gif            
<mx:Button label="Send" click="onSend()"/>
None.gif            
<mx:Button label="Connection" fontWeight="normal" click="onClick()"/>
None.gif        
</mx:ControlBar>
None.gif    
</mx:Panel>
None.gif    
None.gif
</mx:Application>
None.gif

 

      程序运行截图如下:

            SharedObjectFMS.jpg

                                                  图1----FMS状态图

            ChatZhangSan.jpg

                                                图2----聊天客户端(张三)

            ChatLiSi.jpg      

                                          图3----聊天客户端(李四)

            SharedObjectFso.jpg

 

      如上图,在FMS应用目录下创建了一后缀为.fso的文件,这就是永久性的远程共享对象文件名。在使用远程共享的时候,根据实际需求来确定是否使用永久性的远程共享对象,一般做聊天应用我个人建议使用临时远程共享对象(不生成.fso文件),要存储聊天记录可以通过其他方式来保存。

      详细大家可以查看官方提供的文档,在FMS的安装目录下就有,我的是D:\Adobe\Flash Media Server 3\documentation\flashmediaserver_AS3LR\index.html

 

      本文就介绍于此,如文中有什么问题,请大家拍砖指正。本文示例源代码下载

source:http://beniao.cnblogs.com/

转载于:https://www.cnblogs.com/zhouchaoyi/articles/1752296.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值