源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

Flex与.NET互操作(十二):FluorineFx.Net的及时通信应用(Remote Shared Objects)(三)

  • 时间:2021-02-22 09:44 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:Flex与.NET互操作(十二):FluorineFx.Net的及时通信应用(Remote Shared Objects)(三)
FluorineFx所提供的远程共享对象(Remote Shared Objects)和FMS的共享对象的功能是一样,对于熟悉FMS开发的朋友来说,学习FluorineFx的远程共享对象是非常简单的。       共享对象可以在服务器端创建,也可以在客户端创建。在客户端创建共享对象的方法和使用FMS开发是一样的,创建一个 NetConnection对象,通过该对象的connect()方法连接到服务器,然后通过SharedObject.getRemote()方法就可以在客户端创建一个远程共享对象。如下实例代码:
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 {   //[img]http://files.jb51.net/upload/20090615201829227.gif[/img] ..do other }
      在FluorineFx的服务器端创建远程共享对象和FMS有很大的区别,FluorineFx的 ISharedObjectService接口提供了专门用于创建远程共享对象的方法 CreateSharedObject(),ApplicationAdapter实现了此接口方法。定义如下:
public bool CreateSharedObject(IScope scope, string name, bool persistent) {       ISharedObjectService service = (ISharedObjectService)ScopeUtils.GetScopeService(scope, typeof(ISharedObjectService));       return service.CreateSharedObject(scope, name, persistent); }
      如果要在服务器端创建远程共享对象,直接调用ApplicationAdapter类中的CreateSharedObject()方法就可以。如下在FluorineFx服务器端创建远程共享对象的代码块:
ISharedObject users_so = GetSharedObject(connection.Scope, "OnLineUsers"); if (users_so == null) {        //创建共享对象         CreateSharedObject(connection.Scope, "OnLineUsers"false);         users_so = GetSharedObject(connection.Scope, "OnLineUsers"); }
      要想更新共享对象里的数据客户端还是使用setProperty()方法,而FluorineFx的服务器更新共享对象的方法则与 FMS不一样,使用的是FluorineFx.Messaging.Api.IAttributeStore接口提供的SetAttribute()和 RemoveAttribute()方法来更新共享对象里的数据。       陆续介绍了这么多,下面通过一个案例来看看该这么去应用远程共享对象。比如做IM、视频聊天、视频会议等及时通信类型的应用中,用户上线下线的频率非常高,这时候我们就可以使用远程共享对象去做在线用户的数据同步。        首先建立FluorineFx服务库,并建立一个应用类继承于ApplicationAdapter,通过重写ApplicationAdapter的相关方法来实现应用程序的不同需求,详细如下代码块:
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>         /// 应用程序启动         /// </summary>         /// <param name="application"></param>         /// <returns></returns>         public override bool AppStart(IScope application)         {             Trace.WriteLine("应用程序启动");             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)             {                 //创建共享对象                 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)             {                 //从共享对象中移除当前退出系统用户                 users_so.RemoveAttribute(userName);             }             base.AppDisconnect(connection);         }     } }
      开发好了ApplicationAdapter,还需要对此ApplicationAdapter进行通信配置,在FluorineFx的应用程序目录中添加app.config并进行如下配置:
<?xml version="1.0" encoding="utf-8"?> <configuration>     <application-handler type="Fx.Adapter.MyApp"/> </configuration>
      另外还需要配置一个客户端方法的通信通道,通过FluorineFx网站下的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>
      如上便完成了服务器端的开发,在flash/felx客户端通过NetConnection去连接应用,并根据当前的连接去连接服务器端的远程共享对象,最后通过异步事件来实现数据同步更新。如下程序运行截图:             [img]http://files.jb51.net/upload/20090615201829152.jpg[/img]         此时开多个浏览器窗口测试,不同窗口使用不同的用户名登录,可以很清楚的看到,我们已经实现了在线用户的数据同步功能,可以及时的反映用户上线离线,可以及时的同步在线用户列表的数据。       另外远程共享对象还有一个功能非常强大的特性方法,就是连接到共享对象的客户端之间可以直接广播消息(客户端调用客户端的方法)。就以上面在线用户的案例为例,用户成功登陆服务器我需要广播一条消息,用户退出了我也需要广播一条消息,要实现这个功能就需要通过远程共享的客户端呼叫 (send()方法)来实现,如下代码块:
private function onCallClient(message:String):void {     so.send("onSayMessage",message); }
             远程共享对象的send()方法调用了onSayMessage这个客户端方法来实现对连接到共享对象上的所有客户端广播消息,那么我们的在定义一个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; }
            [img]http://files.jb51.net/upload/20090615201829291.jpg[/img]       如果想实现用户退出广播,可以通过服务器端RPC的方法调用客户端的方法来实现,关于RPC请查看《[url=http://www.cnblogs.com/beniao/archive/2009/06/03/1457603.html]Flex与.NET互操作(十一):基于FluorineFx.Net的及时通信应用(Remote Procedure Call)(二) [/url]》有详细介绍。下面是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 = "连接状态:" + 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>】登陆了系统!");          ");                 }             }             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="登陆服务器" click="connectionServer(event)"                  enabled="{this.txtUserName.text.length>0?true:false}" color="#FFFFFF"/>         </mx:FormItem
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部