FlashCom的
Framework写的很不错,对深入研究actionscript和flashcom都有一定帮助。
把function的几篇相关文章摘读一下
原文出处:
http://blog.funciton.com/en/archives/000254.php
本人对原文做了部分删减,增加了一些原文没有的代码参考。
第一部分
MM的FlashCom Server Framework原本是和
组件相关联的,但是其中添加了不少有用的功能,我们依然可以在不使用FlashCom组件的情况下来使用该Framework(Function组件就是一个例子)。
一个FlashCom Server只能运行一个application对象以及相关事件,比如说,我们只能在main.asc文件中
定义一个application.onAppStart, application.onConnect等,但问题是,我们如何管理每个组件类的私有
应用程序事件。
下面我们来一步一步揭开Framework的神秘面纱。
Framework怎样对应用程序对象建立广播(类似于FlashMX2004中的EventDispatcher 类和Flash MX中的AsBroadcaster对象)?
它的方式是否就像是一个应用程序事件通过广播调用和调用所有的对象事件?
那么这些组件放置在gFrameworkFC对象的什么地方?
注:gFrameworkFC对象是由Framwork建立的一个全局对象
每一个组件
实例都基于gFrameworkFC对象中的components对象,如果有更多的对象被建立会是什么情况?
它们通过基于
服务器端类的命名空间放置在不同的位置,并且可以实例化。
例如:FCChat组件类的命名空间是
gFramework.components.FCChat.clientSideComponentInstance
如果我们有多个chat组件,FCChat对象需要两个属性来指向不同的组件实例。
我们没有涉及到客户端的组件实例,事实上我们仅仅需要操作服务器端对象而无需直接操作客户端对象。
Framework具有下面些常用的对象
gFrameworkFC 全局对象
clientGlobals 客户端全局对象
components 组件对象
第二部分
我们都知道服务器端的参数不能传递一个真正的数组,我们需要把数据连接起来,这给我们传值带来很大的不便。
事实上FlashCom的工程师通过Framework解决了这个问题,他们尝试过很多种方法,直到FlashCom1.5 updater1出来后,这个问题才真正的解决。通过gFrameworkFC全局对象的__toarray__方法,究竟如何使用呢,我们先来看下该方法的定义。
- gFrameworkFC.__toarray__ = function(obj) {
- if (
typeof(obj) != 'object' || obj.constructor == Array || obj[ 'length' ] == null )- return
obj;- var
a = new Array(obj.length)- for ( var
i = 0; i < obj.length; i++ )a[ i ] = obj[ i ];- return
a;- }
使用的时候我们只需要通过调用对象的arguments参数,通过__toarray__方法返回一个真正的数组对象。如:
- application.onConnect = function (){// arguments is not a real arrayvar t = gFrameworkFC.__toarray__( arguments );
- }
这样,t就是一个数组,我们可以对它进行诸如concat, splice, pop, push之类的数组操作了。
另外一个很重要的地方是,每个连接的客户端对象都将通过Framework赋予一个唯一的ID,当应用程序重新启动的时候这个ID的值初始化为 0 ,这个ID被getClientGlobals和getClientLocals方法所调用,这在下个部分会详细描述。
你可以通过__ID__ 属性来访问,如果你使用服务器端组件的话,也可以使用下面的方式访问到
- //FCMySSComponent是服务器端的组件实例名
- var id = FCMySSComponent.getClientID(client);
其实很简单但是非常有意思,你说呢?
第三部分
现在来讲述getClientGlobalStorage和getClientLocalStorage方法。
在gFrameworkFC对象中并没有直接定义getClientGlobalStorage和getClientLocalStorage方法,只是定义了getClientGlobals方法。
- gFrameworkFC.getClientGlobals = function(client) {
- return
this.clientGlobals[client.__ID__];- }
getClientGlobalStorage和getClientLocalStorage方法就是在components对象中定义的
- FCComponent.prototype.getClientGlobalStorage = function( client ) {
- return
gFrameworkFC.getClientGlobals(client);- }
-
FCComponent.prototype.getClientLocalStorage = function( client ) {- if (
this.clientLocalStorage == null )-
this.clientLocalStorage = new Object();- var
cls = this.clientLocalStorage[client.__ID__];- if (
cls == null )-
cls = this.clientLocalStorage[client.__ID__] = new Object();- return
cls;- }
这两个方法非常有用,用来区分全局
变量和组件实例变量。
这两个方法的调用参数是客户端对象(这个客户端对象具有一个唯一的__ID__)返回一个新的对象.
如果我们给getClientGlobalStorage设置了某个属性,就可以从任何地方访问到该属性值;但是我们如果给getClientLocalStorage对象设置属性值后,只能在该组件实例中访问该属性值,同时也是限制客户端(唯一的连接__ID__可以访问)。
那么如何才能从其它客户端对象访问 getClientGlobalStorage ?
我们只需要在调用对象的方法的时候包含 __ID__ 属性就可以,这个 __ID__ 属性值必须是唯一的。
当我们需要释放某个组件实例的变量可以用releaseLocalStorage方法
releaseLocalStorage方法在components 组件对象中定义
- FCComponent.prototype.releaseLocalStorage = function( client ) {
- if (
this.clientLocalStorage != null )delete this.clientLocalStorage[client.__ID__];- }
使用的时候很简单:
- FCMySSComponent.releaseLocalStorage(Client);
建议在用户断开连接的时候释放存储,当然你可以保留对象,但是要记住每次新的客户端连接(甚至是之前的同一个用户)都会得到一个新的客户端 __ID__ 值,所以对象在以后将不会被再次使用。
- //我们通常在服务器端组件连接的时候会定义两个对象
- var cglobal = this.getClientGlobalStorage(client);
- var
clocal = this.getClientLocalStorage(client);//在断开连接的时候会释放this.releaseLocalStorage(client);
这种方法在很多组件中被使用。
参考文章:
http://www.macromedia.com/devnet ... cles/framework.html