本地共享对象SharedObject的体验,有兴趣的朋友可以去:www.vini123.com/chatroom/ 体验。
(1)注册一个账号,然后登陆进去。
(2)关闭该浏览器窗口。
(3)然后再输入网址,进去。

SharedObject(共享对象)分本地共享对象和服务器共享对象。本地SharedObject(共享对象)可以作为cookie来使用,服务器SharedObject(共享对象),FMS用到。相当于FMS里边的broadcastMsg效果。本质是共享实时数据。现在,分两种情况来把SharedObject(共享对象)的用法分享下。加深下记忆。

其实,远程共享对象还可以分为在服务器上存储共享数据,相当于本地的一样,只是将数据存储在服务器上。连接服务器成功就可以用。还有一个就是实时共享数据。也就是上边所说的broadcastMsg的效果。



SharedObject,在flash.net包下。直接继承EventDispatcher。

用的时候,要导入:import flash.net.SharedObject;

var userSo:SharedObject=SharedObject.getLocal("soname");

getLocal用来获取已经存在的共享对象或创建一个共享对象。它有三个参数。第一个参数是必须的。
public static function getLocal(name:String, localPath:String = null, secure:Boolean = false):SharedObject

第一个参数name:String,对象的名称,该名称可以包裹斜杠("/"),但不允许使用空格和这些字符(~ % & \ ; : " ' , < > ? # )
第二个参数localPath:String = null,创建共享对象的完整路劲或部分路径。如果未指定,则使用完整路径。若允许级别最高的方法是将 localPath 设置为 /(斜杠)。
第三个参数secure:Boolean = false,用来确定共享对象访问是否只限于通过HTTPS连接传递的SWF文件。默认值是flase。

第一种:本地共享对象。
本地共享对象,只用第一个参数就可以了。取一个和别人不一样的对象名字。比如你的域名是。hao123.com ,你可以将getLocal的第一个参数写成 “hao123/userCookies”, 是支持斜杠的。

对于你写程序的人。你可以知道你想要保存的数据。所以,创建共享对象后。你可以判断该共享对象是否保存了数据,也就是你想保存的数据。假如你想要用 userSo.data.username="vini"; 来保存登陆用户的用户名字。那么,你就可以首先这样判断
if(userSo.data.username==undefined||userSo.data.username == null)
{

}

如果上边的条件成立。表示,你还没有将共享对象写入本地。这个时候,你就可以这样。

if(userSo.data.username==undefined||userSo.data.username == null)
{
userSo.clear();
userSo.data.username=“七月羽歌”;
userSo.flush();
return;
}

这样你就可以将共享对象写入本地了。上边用到了几个方法,先解释写。clear() 方法,清除所有数据,并从磁盘删除共享对象。
也可以用 delete userSo.data.username; 来删除这个属性。
flush() 方法,将本地共享对象写入本地文件。虽然,flash player 会在共享对象会话结束时,将本地共享对象写入写入本地文件。但是,建议还是手动用flush()方法写入的好。

data属性。将共享对象写入本地,这个很重要。要保存的数据给SharedObject(共享对象)的data属性。eg: userSo.data.sex="boy"; 获取共享对象的数据也是用这个。

写入数据的时候,可视对象那些数据不能保存,比如MoveClip,Sprite,按钮等。手动用flush()方法写入的时候,会有三种情况。flush()方法,有返回值的。如果用户禁止存储lso文件或者其他原因造成数据写入失败,flush()函数会报错。如果磁盘剩余空间不足,会弹出对话框,让用户选择增加磁盘存储空间,数据会写入成功。如果磁盘空间充足,并且数据写入成功,函数会返回 flushed 。如果返回SharedObjectFlushStatus.PENDING,可以对共享对象进行侦听。
如:
if (userSo.flush() == SharedObjectFlushStatus.PENDING)
{
userSo.addEventListenr(NetStatusEvent.NET_STATUS, onFlushStatus);
}
会根据用户的选择返回不同的结果:
function onFlushStatus(e:NetStatusEvent):void
{
switch (e.info.code)
{
case "SharedObject.Flush.Success" :
trace("写入成功");
break;
case "SharedObject.Flush.Failed" :
trace("写入失败");
break;
}
}

第二种:远程共享对象。
远程共享对象所用到的属性和方法就比本地共享对象的多了。以fms为例。
建立远程共享对象之前,先创建一个NetConnection对象。然后,去建立连接。这个时候,去侦听连接状态,会得到返回值。
当返回"NetConnection.Connect.Success"时,表示连接成功。
eg:
var nc:NetConnection=new NetConnection();
nc.client = new NetClient(this);
nc.connect("rtmp://localhost/TestShared");
nc.addEventListener(NetStatusEvent.NET_STATUS,netStatusHandler);
mySo.send("clientBroadCastMessage");

function clientBroadCastMessage()
{
trace("哈哈,我send了!");
}
function netStatusHandler(e:NetStatusEvent)
{
var code:String = e.info.code;
switch (code)
{
case "NetConnection.Connect.Success" :
creatSo();
break;
default :
break;
}
}

当建立NetConnection成功后,就可以开始建立远程共享了。

mySo = getSharedObject(userName);
mySo.client = nc.client;
mySo.addEventListener(SyncEvent.SYNC,syncHandler);

function getSharedObject(soName):SharedObject
{
var sharedObject:SharedObject = SharedObject.getRemote(soName,nc.uri,false);
sharedObject.connect(nc);
return sharedObject;
}

function syncHandler(e:SyncEvent)
{
for(var i in e.target.data)
{
trace(i,"*******",e.target.data[i]);
}
}

下边来分析下这段代码:
public static function getRemote(name:String, remotePath:String = null, persistence:Object = false, secure:Boolean = false):SharedObject
getRemote()函数,有四个参数:
第一个参数 name:String ,对象的名称。这个和本地共享对象一样的。
第二个参数 remotePath:String = null,将存储共享对象的服务器的URI. 此 URI 必须与传递给 SharedObject.connect() 方法的 NetConnection 对象的 URI 相同。
第三个参数 secure:Boolean = false,指定共享对象数据属性的特性是本地永久存储还是远程永久存储,或者同时进行本地永久存储和远程永久存储。此参数还可指定共享对象的本地存储位置。默认值false,指定客户端或服务器上的共享对象不是永久性的。
true,指定只有服务器上的共享对象是永久性的。
第四个参数 secure:Boolean (default = false) — 确定对此共享对象的访问是否只限于通过 HTTPS 连接传递的 SWF 文件。
远程共享对象,要指定他的client,就是共享对象调用回调方法的对象。这个很重要。
SyncEvent.SYNC,对远程对象SYNC事件的侦听。共享对象的某些属性发生改变时,会通知服务器该属性服务器某属性值已经改变,然后通知客户端上的SYNC事件。怎样去改变共享对象的属性呢,就用到setProperty () 方法。该方法的作用就是上边那句话。还有SharedObject.setProperty() 方法实现了 setDirty() 方法。 大多数情况下,例如当属性的值为 String 或 Number 等原始类型时,应使用 setProperty(),而不使用 setDirty。 然而,当某个属性的值是一个包含其自身属性的对象时,则使用 setDirty() 来指示该对象中的值的更改时间。 通常,最好调用 setProperty() 而不要调用 setDirty(),因为 setProperty() 只在值被更改的时候更新属性值,而 setDirty() 则强制所有订阅客户端进行同步。
eg:
mySo.setProperty("userName",userName);
mySo.setProperty("chatConnect",inTxt.text);

再来说说 send()函数,对连接到指定远程共享对象的所有客户端(包裹发送消息的客户端)广播一条消息。如果用send,可以做最简单方便的flash聊天室。

共享对象不用了就关掉吧。close(); 函数关掉共享对象,再将其设置成null吧。

上边漏说了一个 服务器端同学文件的书写。fms的通讯文件是.asc文件。语法还是曾经的as1,as2.下边贴出来。

application.onAppStart=function()
{
trace("哇哈,我要开始啦");
}

application.onConnect=function(newClient,userName)
{
var len=application.clients.length;
trace(len);
if(len>0)
{
for(var i=0;i

package 
{
    import flash.display.Sprite;
    import flash.net.SharedObject;
    import flash.events.NetStatusEvent;

    public class Main extends Sprite
    {
        private var userSo:SharedObject;
        private var obj:Object = {};
        public function Main():void
        {
            setCookies();
        }

        private function setCookies()
        {
            userSo = SharedObject.getLocal("testCookie");

            //不会触发的;
            userSo.addEventListener(NetStatusEvent.NET_STATUS,netStatusHandler);

            if (userSo.data.userName == undefined || userSo.data.userName == null)
            {
                userSo.clear();
                userSo.data.userName = "七月羽歌";
                userSo.data.sex = "girl";
                userSo.data.userType = "5";
                userSo.flush();
                return;
            }
            obj.userName = userSo.data.userName;
            obj.sex = userSo.data.sex;
            obj.uesrType = userSo.data.userType;
            userSo = null;//因为只在登陆的时候用到。以后就不用了。
        }

        private function netStatusHandler(e:NetStatusEvent)
        {
            trace(e.info.code);
        }
    }
}