Actionscript 3 SharedObject似乎正在缓存
我对SharedObject有一个稍微不寻常的情况: 情况:我们有一个基于SWF(浏览器)的应用程序在一台本地机器上运行。SWF访问本地内容,每XX秒/分钟/小时重新加载一次 应用程序的状态必须以JSON样式存储在单个SharedObject中(这是使用“/”参数将其强制为全局) SWF在进行任何状态更新之前加载SO,并在更新之后立即正确调用flush()以保存状态 问题:一切正常,但偶尔会出现这样的情况:相同SWF的两个实例在不同的实例中同时存在,并且都访问相同的SharedObject 第二个必须从第一个开始控制SO,通过每个SWF实例将其实例状态设置为存储在SO中的递增数字(SWF Idx) 两者都是在进行任何更新之前加载文件,并检查版本号,如果保存的SWF Idx高于其自身版本号,则将禁用它们自己。不幸的是,第一个SWF实例不知何故没有加载SharedObject的最新版本,因为它跟踪的是原始版本(例如22),而不是现在更新的版本(例如23)。而第二个SWF正在追踪23,SO包含23 浏览器是否有可能缓存SO 测试 我目前正在测试这种情况,在本地运行一个浏览器实例,然后启动第二个。在每个州之前和之后制作SO的副本。 我还通过IntelliJ运行了第一个和第二个,可以看到每次都在调用和检查Actionscript 3 SharedObject似乎正在缓存,actionscript-3,flash,shared-objects,Actionscript 3,Flash,Shared Objects,我对SharedObject有一个稍微不寻常的情况: 情况:我们有一个基于SWF(浏览器)的应用程序在一台本地机器上运行。SWF访问本地内容,每XX秒/分钟/小时重新加载一次 应用程序的状态必须以JSON样式存储在单个SharedObject中(这是使用“/”参数将其强制为全局) SWF在进行任何状态更新之前加载SO,并在更新之后立即正确调用flush()以保存状态 问题:一切正常,但偶尔会出现这样的情况:相同SWF的两个实例在不同的实例中同时存在,并且都访问相同的SharedObject 第二
SharedObject.getLocal
我在下面介绍了我正在使用的代码的基本知识,其中:
=是公共SharedObject变量\uu so
=是AS3中存储当前实例SWF索引的私有变量\u thiswfidx
=最新的SWF索引\uuu so.data.activeSWFIdx
SharedObject.getLocal(_SO_ID, "/");
我正在做的检查是:
if (_thisSWFIdx < __so.data.activeSWFIdx) {
__amActiveSWF = false;
}
附加信息:
- 这在mac和windows上都运行
- FlashPlayer 10.3
- 纯AS3
- 用IntelliJ编译
- FF、Chrome和IE中存在同样的问题
- 主机Macbook
我在文档或现有线程中找不到任何内容,因此非常感谢您的帮助。经过一个小测试后,我注意到了您提到的行为:在第二个SWF更新
SharedObject
后,第一个只有在重新加载后才能获得新值
为了避免这种情况,我认为,作为一种解决方法,您可以使用第二个SWF,它只通过读/写数据来处理SharedObject
为此,以这个例子为例:
so.swf:将读取和写入数据的swf
var shared_object_name:String = 'so';
var shared_object:SharedObject = SharedObject.getLocal(shared_object_name, '/');
// get the id
function get_id(): int {
return shared_object.data.id ? shared_object.data.id : -1;
}
// set the id
function set_id(new_id:int): void {
shared_object.data.id = new_id;
shared_object.flush();
}
app.swf:您的全局应用程序将使用“so.swf”执行SharedObject
的操作:
var init:Boolean = true;
var swf_id:int = 1;
var swf_disabled:Boolean = false;
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, on_SWFLoad);
loader.load(new URLRequest('so.swf'));
function on_SWFLoad(e:Event): void
{
var loaded_swf:MovieClip = MovieClip(loader.content);
var current_id:int = loaded_swf.get_id();
// if it's initial run
if(init){
init = false;
if(current_id > 0){
swf_id = current_id + 1;
}
loaded_swf.set_id(swf_id);
} else { // we are verifying if there is a new active SWF
if (swf_id <= current_id) {
swf_disabled = true;
}
}
}
function stage_onPress(e:MouseEvent){
// if this SWF is disabled, stop getting the "id"
if(swf_disabled){
stage.removeEventListener(MouseEvent.CLICK, stage_onPress);
return;
}
// otherwise, get the "id" to verify if there is another active SWF
loader.load(new URLRequest('so.swf'));
}
stage.addEventListener(MouseEvent.CLICK, stage_onPress);
var init:Boolean=true;
变量swf_id:int=1;
var swf_禁用:布尔值=false;
变量加载器:加载器=新加载器();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,on_SWFLoad);
loader.load(newurlRequest('so.swf'));
_SWFLoad上的函数(e:事件):无效
{
var-loaded\u-swf:MovieClip=MovieClip(loader.content);
var current_id:int=loaded_swf.get_id();
//如果是首次运行
if(init){
init=false;
如果(当前id>0){
swf_id=当前_id+1;
}
加载的swf.set\u id(swf\u id);
}否则{//我们正在验证是否存在新的活动SWF
如果(swf_id经过一个小测试,我注意到了您提到的行为:在第二个swf更新SharedObject
后,第一个swf只能在重新加载后才能获得新值
为了避免这种情况,我认为,作为一种解决方法,您可以使用第二个SWF,它只通过读/写数据来处理SharedObject
为此,以这个例子为例:
so.swf:将读取和写入数据的swf
var shared_object_name:String = 'so';
var shared_object:SharedObject = SharedObject.getLocal(shared_object_name, '/');
// get the id
function get_id(): int {
return shared_object.data.id ? shared_object.data.id : -1;
}
// set the id
function set_id(new_id:int): void {
shared_object.data.id = new_id;
shared_object.flush();
}
app.swf:您的全局应用程序将使用“so.swf”执行SharedObject
的操作:
var init:Boolean = true;
var swf_id:int = 1;
var swf_disabled:Boolean = false;
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, on_SWFLoad);
loader.load(new URLRequest('so.swf'));
function on_SWFLoad(e:Event): void
{
var loaded_swf:MovieClip = MovieClip(loader.content);
var current_id:int = loaded_swf.get_id();
// if it's initial run
if(init){
init = false;
if(current_id > 0){
swf_id = current_id + 1;
}
loaded_swf.set_id(swf_id);
} else { // we are verifying if there is a new active SWF
if (swf_id <= current_id) {
swf_disabled = true;
}
}
}
function stage_onPress(e:MouseEvent){
// if this SWF is disabled, stop getting the "id"
if(swf_disabled){
stage.removeEventListener(MouseEvent.CLICK, stage_onPress);
return;
}
// otherwise, get the "id" to verify if there is another active SWF
loader.load(new URLRequest('so.swf'));
}
stage.addEventListener(MouseEvent.CLICK, stage_onPress);
var init:Boolean=true;
变量swf_id:int=1;
var swf_禁用:布尔值=false;
变量加载器:加载器=新加载器();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,on_SWFLoad);
loader.load(newurlRequest('so.swf'));
_SWFLoad上的函数(e:事件):无效
{
var-loaded\u-swf:MovieClip=MovieClip(loader.content);
var current_id:int=loaded_swf.get_id();
//如果是首次运行
if(init){
init=false;
如果(当前id>0){
swf_id=当前_id+1;
}
加载的swf.set\u id(swf\u id);
}否则{//我们正在验证是否存在新的活动SWF
如果(swf_id闻起来像是一个竞争条件。这肯定有一定的风险,我需要处理,但对于上面的问题,我已经设置了一个测试,在这个测试中,我有一个明确的安全时间窗口,例如实例B控制并增加SO,而实例a不进行交互。在这个实例a交互后,但仍然读取旧值。@Visualife到我的据了解,浏览器与此无关,这是Flash播放器的问题。您是如何设置\u thiswfidx
的值的?@akmozo\u thiswfidx是一个AS3变量。每个SWF只设置一次,如果SO不包含activeSWFIdx,则设置为1,如果activeSWFIdx存在,则设置为activeSWFIdx的增量。在这两种情况下,SO都会更新(an正在更新)。@Visualife我认为您的SWF应该每隔n
秒进行一次验证(例如)如果它总是活动的,从SO获取当前ID,然后在有另一个活动SWF时禁用它自己…闻起来像是一个竞赛条件。这肯定有一定的风险,我需要处理,但对于以上我已经做了