欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Flex與.NET互操作(十二):FluorineFx.Net的及時通信應(yīng)用(Remote Shared Objects)(三)

 更新時間:2009年06月15日 20:18:33   作者:  
遠程共享對象(Remote Shared Objects) 可以用來跟蹤、存儲、共享以及做多客戶端的數(shù)據(jù)同步操作。只要共享對象上的數(shù)據(jù)發(fā)生了改變,將會把最新數(shù)據(jù)同步到所有連接到該共享對象的應(yīng)用程序客戶端。

FluorineFx所提供的遠程共享對象(Remote Shared Objects)和FMS的共享對象的功能是一樣,對于熟悉FMS開發(fā)的朋友來說,學(xué)習(xí)FluorineFx的遠程共享對象是非常簡單的。

      共享對象可以在服務(wù)器端創(chuàng)建,也可以在客戶端創(chuàng)建。在客戶端創(chuàng)建共享對象的方法和使用FMS開發(fā)是一樣的,創(chuàng)建一個 NetConnection對象,通過該對象的connect()方法連接到服務(wù)器,然后通過SharedObject.getRemote()方法就可以在客戶端創(chuàng)建一個遠程共享對象。如下實例代碼:

private function connectionServer():void
{
    var nc:NetConnection 
= new NetConnection();
    nc.connect(
"rtmp://localhost:1617/SOAPP","username","password")
    nc.addEventListener(NetStatusEvent.NET_STATUS,onStatusHandler);
    nc.client 
= this;
}

private function onStatusHandler(event:NetStatusEvent):void
{
    
if(event.info.code == "NetConnectin.Connect.Success")
    {
        createSharedObject();
    }
}

private function createSharedObject():void
{
    var so:SharedObject 
= SharedObject.getRemote("OnLineUsers",nc.uri,false);
    so.addEventListener(SyncEvent.SYNC,onSyncHandler);
    so.connect(
this.nc);
    so.client 
= this;
}

private function onSyncHandler(event:SyncEvent):void
{
  
//..do other
}

      在FluorineFx的服務(wù)器端創(chuàng)建遠程共享對象和FMS有很大的區(qū)別,F(xiàn)luorineFx的 ISharedObjectService接口提供了專門用于創(chuàng)建遠程共享對象的方法 CreateSharedObject(),ApplicationAdapter實現(xiàn)了此接口方法。定義如下:

public bool CreateSharedObject(IScope scope, string name, bool persistent)
{
      ISharedObjectService service 
= (ISharedObjectService)ScopeUtils.GetScopeService(scope, typeof(ISharedObjectService));
      
return service.CreateSharedObject(scope, name, persistent);
}

      如果要在服務(wù)器端創(chuàng)建遠程共享對象,直接調(diào)用ApplicationAdapter類中的CreateSharedObject()方法就可以。如下在FluorineFx服務(wù)器端創(chuàng)建遠程共享對象的代碼塊:

ISharedObject users_so = GetSharedObject(connection.Scope, "OnLineUsers");
if (users_so == null)
{
       
//創(chuàng)建共享對象
        CreateSharedObject(connection.Scope, "OnLineUsers"false);
        users_so 
= GetSharedObject(connection.Scope, "OnLineUsers");
}

      要想更新共享對象里的數(shù)據(jù)客戶端還是使用setProperty()方法,而FluorineFx的服務(wù)器更新共享對象的方法則與 FMS不一樣,使用的是FluorineFx.Messaging.Api.IAttributeStore接口提供的SetAttribute()和 RemoveAttribute()方法來更新共享對象里的數(shù)據(jù)。

      陸續(xù)介紹了這么多,下面通過一個案例來看看該這么去應(yīng)用遠程共享對象。比如做IM、視頻聊天、視頻會議等及時通信類型的應(yīng)用中,用戶上線下線的頻率非常高,這時候我們就可以使用遠程共享對象去做在線用戶的數(shù)據(jù)同步。 

      首先建立FluorineFx服務(wù)庫,并建立一個應(yīng)用類繼承于ApplicationAdapter,通過重寫ApplicationAdapter的相關(guān)方法來實現(xiàn)應(yīng)用程序的不同需求,詳細如下代碼塊:

using System;
using System.Collections.Generic;
using System.Text;
using FluorineFx.Messaging.Adapter;
using FluorineFx;
using FluorineFx.Messaging.Api;
using System.Diagnostics;
using FluorineFx.Messaging.Api.SO;
using FluorineFx.Exceptions;
using FluorineFx.Context;
using FluorineFx.Messaging.Api.Service;
using System.Collections;
using Fx.Adapter.DTO;

namespace Fx.Adapter
{
    
/// <summary>
    
/// 自定義ApplicationAdapter
    
/// </summary>
    [RemotingService]
    
public class MyApp : ApplicationAdapter
    {
        
/// <summary>
        
/// 應(yīng)用程序啟動
        
/// </summary>
        
/// <param name="application"></param>
        
/// <returns></returns>
        public override bool AppStart(IScope application)
        {
            Trace.WriteLine(
"應(yīng)用程序啟動");
            
return true;
        }

        
/// <summary>
        
/// 房間啟動
        
/// </summary>
        
/// <param name="room"></param>
        
/// <returns></returns>
        public override bool RoomStart(IScope room)
        {
            Trace.WriteLine(
"房間啟動");
            
if (!base.RoomStart(room))
                
return false;
            
return true;
        }

        
/// <summary>
        
/// 接收客戶端的連接
        
/// </summary>
        
/// <param name="connection"></param>
        
/// <param name="parameters"></param>
        
/// <returns></returns>
        public override bool AppConnect(IConnection connection, object[] parameters)
        {
            
string userName = parameters[0as string;
            
string password = parameters[1as string;

            
if (password == null || password == string.Empty)
                
throw new ClientRejectedException(null);

            connection.Client.SetAttribute(
"userName", userName);
            
//獲取共享對象(OnLineUsers)
            ISharedObject users_so = GetSharedObject(connection.Scope, "OnLineUsers");
            
if (users_so == null)
            {
                
//創(chuàng)建共享對象
                CreateSharedObject(connection.Scope, "OnLineUsers"false);
                users_so 
= GetSharedObject(connection.Scope, "OnLineUsers");
            }
            
//更新共享對象
            users_so.SetAttribute(userName, userName);
            
return true;
        }

        
/// <summary>
        
/// 加入房間
        
/// </summary>
        
/// <param name="client"></param>
        
/// <param name="room"></param>
        
/// <returns></returns>
        public override bool RoomJoin(IClient client, IScope room)
        {
            Trace.WriteLine(
"加入房間 " + room.Name);
            
return true;
        }

        
/// <summary>
        
/// 離開房間
        
/// </summary>
        
/// <param name="client"></param>
        
/// <param name="room"></param>
        public override void RoomLeave(IClient client, IScope room)
        {
            Trace.WriteLine(
"離開房間 " + room.Name);
            
base.RoomLeave(client, room);
        }

        
/// <summary>
        
/// 用戶退出
        
/// </summary>
        
/// <param name="connection"></param>
        public override void AppDisconnect(IConnection connection)
        {
            
string userName = connection.Client.GetAttribute("userName"as string;
            ISharedObject users_so 
= GetSharedObject(connection.Scope, "OnLineUsers");
            
if (users_so != null)
            {
                
//從共享對象中移除當(dāng)前退出系統(tǒng)用戶
                users_so.RemoveAttribute(userName);
            }
            
base.AppDisconnect(connection);
        }
    }
}

      開發(fā)好了ApplicationAdapter,還需要對此ApplicationAdapter進行通信配置,在FluorineFx的應(yīng)用程序目錄中添加app.config并進行如下配置:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    
<application-handler type="Fx.Adapter.MyApp"/>
</configuration>

      另外還需要配置一個客戶端方法的通信通道,通過FluorineFx網(wǎng)站下的WEB-INF/flex/service-config.xml配置:

<?xml version="1.0" encoding="utf-8" ?>
<services-config>

      <channels>

          <channel-definition id="my-rtmp" class="mx.messaging.channels.RTMPChannel">
               
<endpoint uri="rtmp://{server.name}:1617" class="flex.messaging.endpoints.RTMPEndpoint"/>
          </channel-definition>

      </channels>

</services-config>

      如上便完成了服務(wù)器端的開發(fā),在flash/felx客戶端通過NetConnection去連接應(yīng)用,并根據(jù)當(dāng)前的連接去連接服務(wù)器端的遠程共享對象,最后通過異步事件來實現(xiàn)數(shù)據(jù)同步更新。如下程序運行截圖:

             

      此時開多個瀏覽器窗口測試,不同窗口使用不同的用戶名登錄,可以很清楚的看到,我們已經(jīng)實現(xiàn)了在線用戶的數(shù)據(jù)同步功能,可以及時的反映用戶上線離線,可以及時的同步在線用戶列表的數(shù)據(jù)。

      另外遠程共享對象還有一個功能非常強大的特性方法,就是連接到共享對象的客戶端之間可以直接廣播消息(客戶端調(diào)用客戶端的方法)。就以上面在線用戶的案例為例,用戶成功登陸服務(wù)器我需要廣播一條消息,用戶退出了我也需要廣播一條消息,要實現(xiàn)這個功能就需要通過遠程共享的客戶端呼叫 (send()方法)來實現(xiàn),如下代碼塊:

private function onCallClient(message:String):void
{
    so.send(
"onSayMessage",message);
}

      

      遠程共享對象的send()方法調(diào)用了onSayMessage這個客戶端方法來實現(xiàn)對連接到共享對象上的所有客戶端廣播消息,那么我們的在定義一個onSayMessage方法,如下:

/**
 * 接受客戶端呼叫---此方法必須是public修飾
 
*/
public function onSayMessage(message:Object):void
{
    traceWriteln(message.toString());
}

private function traceWriteln(param:String):void
{
   txtTraceArea.htmlText += param + "\n";
   txtTraceArea.validateNow();
   txtTraceArea.verticalScrollPosition = txtTraceArea.maxVerticalScrollPosition;
}

            

      如果想實現(xiàn)用戶退出廣播,可以通過服務(wù)器端RPC的方法調(diào)用客戶端的方法來實現(xiàn),關(guān)于RPC請查看《Flex與.NET互操作(十一):基于FluorineFx.Net的及時通信應(yīng)用(Remote Procedure Call)(二) 》有詳細介紹。下面是Flex客戶端的完整代碼:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"  
    width
="530" height="378" backgroundGradientAlphas="[1.0, 1.0]" 
    backgroundGradientColors
="[#000000, #686868]" fontSize="12">
    
<mx:Script>
        
<![CDATA[
            import mx.controls.Alert;
            import dotnet.fluorinefx.VO.UserInfo;

            
private var nc:NetConnection;
            
private var so:SharedObject;
            
private var info:UserInfo;

            
private function connectionServer(event:MouseEvent):void
            {
                info 
= new UserInfo();
                info.UserName 
= this.txtUserName.text;
                info.Password 
= this.txtPassword.text;

                nc 
= new NetConnection();
                nc.connect(
"rtmp://localhost:1617/SOAPP",info.UserName,info.Password);
                nc.addEventListener(NetStatusEvent.NET_STATUS,onStatusHandler);
                nc.client 
= this;

                
this.txtUserName.text="";
                
this.txtPassword.text="";
                
this.txtUserName.setFocus();
            }

            
private function onStatusHandler(event:NetStatusEvent):void
            {
                
this.connStatus.text = "連接狀態(tài):" + event.info.code;
                
if(event.info.code == "NetConnection.Connect.Success")
                {
                    
//連接遠程共享對象
                    so = SharedObject.getRemote("OnLineUsers",nc.uri,false);
                    
if(so)
                    {
                        so.addEventListener(SyncEvent.SYNC,onSyncHandler);
                        so.connect(nc);
                        so.client 
= this;
                    }
                    onCallClient(
"用戶【 <font color=\"#4100b9\">"+info.UserName+"</font>】登陸了系統(tǒng)!");
         "
);
                }
            }

            
private function onSyncHandler(event:SyncEvent):void
            {
                var temp:Array 
= new Array();
                
for(var u:String in so.data)
                {
                    
//traceWriteln("異步事件->共享對象:" + u + ":" + so.data[u]);
                    temp.push(so.data[u]);
                }
                
this.userList.dataProvider = temp;
            }

            
private function traceWriteln(param:String):void
            {
                txtTraceArea.htmlText 
+= param + "\n";
                txtTraceArea.validateNow();
                txtTraceArea.verticalScrollPosition 
= txtTraceArea.maxVerticalScrollPosition;
            }

            
private function onCallClient(message:String):void
            {
                so.send(
"onSayMessage",message);
            }
            
/**
             * 接受客戶端呼叫
             
*/
            
public function onSayMessage(message:Object):void
            {
                traceWriteln(message.toString());
            }
        ]]
>
    
</mx:Script>
    
<mx:Label x="24" y="134" id="connStatus" width="288" color="#FFFFFF"/>
    
<mx:List x="342" y="10" height="347" width="160" id="userList" >
    
</mx:List>
    
<mx:Form x="24" y="10" width="236">
        
<mx:FormItem label="用戶名:" color="#FFFFFF">
            
<mx:TextInput id="txtUserName" width="130" color="#000000"/>
        
</mx:FormItem>
        
<mx:FormItem label="密  碼:" color="#FFFFFF">
            
<mx:TextInput id="txtPassword" width="130" 
                color
="#000000" displayAsPassword="true"/>
        
</mx:FormItem>
        
<mx:FormItem label="">
            
<mx:Button label="登陸服務(wù)器" click="connectionServer(event)" 
                enabled
="{this.txtUserName.text.length&gt;0?true:false}" color="#FFFFFF"/>
        
</mx:FormItem>
    
</mx:Form>
    
<mx:TextArea x="24" y="174" width="288" height="153" alpha="1.0" 
        backgroundColor
="#F2D2D2" backgroundAlpha="0.26" color="#FFFFFF" 
        id
="txtTraceArea" borderColor="#FFFFFF"/>
</mx:Application>
       }
            }

            private function onSyncHandler(event:SyncEvent):void
            {
                var temp:Array 
= new Array();
                
for(var u:String in so.data)
                {
                    
//traceWriteln("異步事件->共享對象:" + u + ":" + so.data[u]);
                    temp.push(so.data[u]);
                }
                
this.userList.dataProvider = temp;
            }

            
private function traceWriteln(param:String):void
            {
                txtTraceArea.htmlText 
+= param + "\n";
                txtTraceArea.validateNow();
                txtTraceArea.verticalScrollPosition 
= txtTraceArea.maxVerticalScrollPosition;
            }

            
private function onCallClient(message:String):void
            {
                so.send(
"onSayMessage",message);
            }
            
/**
             * 接受客戶端呼叫
             
*/
            
public function onSayMessage(message:Object):void
            {
                traceWriteln(message.toString());
            }
        ]]
>
    
</mx:Script>
    
<mx:Label x="24" y="134" id="connStatus" width="288" color="#FFFFFF"/>
    
<mx:List x="342" y="10" height="347" width="160" id="userList" >
    
</mx:List>
    
<mx:Form x="24" y="10" width="236">
        
<mx:FormItem label="用戶名:" color="#FFFFFF">
            
<mx:TextInput id="txtUserName" width="130" color="#000000"/>
        
</mx:FormItem>
        
<mx:FormItem label="密  碼:" color="#FFFFFF">
            
<mx:TextInput id="txtPassword" width="130" 
                color
="#000000" displayAsPassword="true"/>
        
</mx:FormItem>
        
<mx:FormItem label="">
            
<mx:Button label="登陸服務(wù)器" click="connectionServer(event)" 
                enabled
="{this.txtUserName.text.length&gt;0?true:false}" color="#FFFFFF"/>
        
</mx:FormItem>
    
</mx:Form>
    
<mx:TextArea x="24" y="174" width="288" height="153" alpha="1.0" 
        backgroundColor
="#F2D2D2" backgroundAlpha="0.26" color="#FFFFFF" 
        id
="txtTraceArea" borderColor="#FFFFFF"/>
</mx:Application>

相關(guān)文章

最新評論