AS3中实现URLLoader循环下载更新游戏报错求助
解决AS3 URLLoader循环请求的IO流错误问题
这个问题我太熟悉了——你现在的代码是请求一完成就立刻发起下一次请求,相当于没有任何间隔地疯狂调用,这会导致两个核心问题:一是Flash Player的网络连接池被快速占满,来不及释放旧连接就新建请求,触发Stream Error;二是你完全没处理任何IO错误,一旦出现网络波动或者服务器响应慢,错误就会直接抛出来没人管。
问题根源拆解
- 无间隔连续请求:每次请求完成立刻递归调用
getState(),没有给系统留出释放网络连接的时间,也容易触发服务器的频率限制,被拒绝后续请求。 - 缺失错误处理:你的
URLLoader只加了COMPLETE监听,完全没处理IO_ERROR事件,所以一旦出现网络问题,错误就会变成未处理的异常。 - 频繁创建URLLoader实例:每次请求都新建一个
URLLoader,会造成不必要的资源开销,长期运行可能导致内存泄漏。
修正后的完整代码
下面是调整后的代码,解决了这些问题:
// 复用URLLoader实例,避免频繁创建 var stateLoader:URLLoader; // 设置请求间隔,根据你的游戏需求调整,这里设为1秒 var requestDelay:int = 1000; function initLoader():void { stateLoader = new URLLoader(); // 监听请求完成事件 stateLoader.addEventListener(Event.COMPLETE, onStateLoaded); // 必须添加IO错误监听,捕获网络异常 stateLoader.addEventListener(IOErrorEvent.IO_ERROR, onLoadError); } function startStateRequest():void { // 如果loader还没初始化,先初始化 if (!stateLoader) { initLoader(); } try { stateLoader.load(new URLRequest("http://localhost/mySite/index.php")); } catch (e:Error) { trace("请求发送失败:" + e.message); // 发送失败也安排下一次请求 scheduleNextRequest(); } } function onStateLoaded(event:Event):void { // 这里处理你的游戏更新逻辑 var loader:URLLoader = URLLoader(event.target); var updateData:String = loader.data; trace("收到更新数据:" + updateData); // 不要直接递归调用,用延迟安排下一次请求 scheduleNextRequest(); } function onLoadError(event:IOErrorEvent):void { trace("加载出错:" + event.text); // 出错后可以选择重试,这里直接安排下一次请求 scheduleNextRequest(); } function scheduleNextRequest():void { // 用setTimeout设置间隔,避免无间隔连续请求 setTimeout(startStateRequest, requestDelay); } // 启动第一次请求 startStateRequest();
关键修改说明
- 复用URLLoader:只初始化一次
URLLoader实例,重复使用,减少资源消耗。 - 添加错误处理:通过
IOErrorEvent.IO_ERROR监听捕获网络错误,避免未处理的异常抛出。 - 设置请求间隔:用
setTimeout给请求之间留出缓冲时间,让旧连接有足够时间释放,也不会给服务器造成过大压力。 - 异常捕获:在
load方法外面加了try-catch,处理请求发送时的同步错误。
额外注意事项
- 调整
requestDelay的值:不要设得太小,比如小于500毫秒,否则还是可能触发服务器的频率限制或者连接池问题。 - 跨域请求问题:如果你的SWF和PHP不在同一个域名下,需要确保服务器根目录有正确的
crossdomain.xml文件,否则会触发跨域IO错误。 - 重试策略优化:如果需要,可以给错误重试添加次数限制,比如连续失败3次就暂停一段时间再重试,避免无效请求浪费资源。
内容的提问来源于stack exchange,提问作者user1512064
相关产品推荐
相关产品推荐

