H5游戏如何应对网络不稳定[超时/重发/加载失败]

H5游戏相比其他任何一种游戏而言,网络不稳定所带来的影响是最大的

一方面是玩游戏的场合,无论是3/4G还是wifi信号都不是很靠谱,如果再加上地铁电梯等场景,就更糟了

另一方面是H5自身既要与游戏服通信又要与资源服务器通信,尤其在新玩家没有缓存的情况下,网络请求比原生手游多很多倍

因此,在玩家网络不稳定的情况下,努力提升游戏体验避免用户流失,是十分必要的

 

然而,虽然生活中网络不稳定是常态,但是在开发过程中却非常难以模拟和重现(除非团队里有真正资深的测试,每天跑到wifi一格的地方给你测试...)

今天就结合葫芦娃H5上线3个月以来的经验(各种毁天灭地大bug)来讨论以下几个需要注意的点

转载注明http://www.cnblogs.com/billyrun/articles/8311765.html

 

1.http超时回调

短连接一般采用XMLHttpRequest

调用的时候一定要处理超时和错误

错误可以用http状态码判断

超时需要手动设置XMLHttpRequest对象的timeout/ontimeout属性

若不设置则timeout默认是-1,表示没有超时时限

这显然是不对的,长时间没收到响应的时候页面就傻了

 

以下引用文档中的例子

注意timeout/ontimeout的设置位置应该在调用open之后,调用send之前

https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest/timeout

var xhr = new XMLHttpRequest();
xhr.open('GET', '/server', true);
xhr.timeout = 2000; // 超时时间,单位是毫秒
xhr.onload = function () {
  // 请求完成。在此进行处理。
};
xhr.ontimeout = function (e) {
  // XMLHttpRequest 超时。在此做某事。
};
xhr.send(null);

  

2.http/websocket重发请求

刚写了为XMLHttpRequest对象设置超时属性

若是长连接,使用websocket的话,并没有简单的设置方法

可以自己写一个轮询来判断某一次请求是否超时

大致思路如下:

设置过期时间,如5s

客户端每次发包时在数据包插入唯一ID,并将ID与当前时刻一并记录在客户端

客户端每秒轮询,检查所记录的ID时刻是否到达过期时间,若过期则将ID清除

收到服务端返回数据包时,取出唯一ID

若客户端仍记录有该ID,解析该回包,并移除该记录;

若客户端没有记录此ID,说明已经超时,直接丢弃该回包

 

然而对于一些关键请求(无论http还是websocket)

仅仅预防超时还是不够的,在超时的时候还需要做重发,以确保游戏逻辑通畅

重发的设计思路是

保存每次请求的全部参数(包括url/正确回调/错误回调/超时回调等)

当超时发生时重新调用一次,具体的场景可以结合弹框让用户选择是否需要重发

 

3.资源加载失败

对全体玩家而言,游戏中所有的动态加载其实都有很高的失败可能性

然而在开发过程中几乎不可能体会到!

以官方CCGame.js加载游戏脚本的代码为例

// Load game scripts
var jsList = config[CONFIG_KEY.jsList];
if (jsList && jsList.length > 0) {
    cc.loader.load(jsList, function (err) {
        if (err) throw new Error(JSON.stringify(err));
        self._prepared = true;
        if (cb) cb();
        self.emit(self.EVENT_GAME_INITED);
    });
}

加载回调函数中第一个参数是err

这里err是一个空对象或数组

加载回调的处理原则如下

3.1判断加载是否成功

若加载失败,那么无论加载的是脚本还是资源,失败了都是不可用的!

所以成功和失败必然是两套逻辑

如以上代码if (err) throw new Error(JSON.stringify(err));

遇到错误抛出异常并停止脚本运行

3.2加载失败如何处理

并不是所有加载都可以在失败时throw error或return

若脚本或关键的资源加载失败,一定要手动重新加载!一些场景还要提示用户

当出错时err数组中的数据就是未加载成功的资源url

因此可以这样加载尚未成功的资源cc.loader.load(err , function(...){...})

理论上来讲是一个递归调用,把必要的资源加载到成功为止

当然也可以做一些限制,比如连续失败3次就告诉用户当前网络实在太差了...

3.3加载回调容易出现的错误

资源加载往往都会被封装成更易用的方法

封装过程中一般统一去处理加载错误的情况

而传入的回调函数一般都是仅在加载成功时才执行的

若需要严格判断加载的数量,比如预加载的进度条显示

则一定要考虑加载失败的情况,不然容易出现加载走不到100%这种事

 

 

http://www.sohu.com/a/216766512_229934

最后热烈庆祝葫芦娃H5被某媒体评为年度最佳

hiahiahia

 

转载于:https://www.cnblogs.com/billyrun/articles/8311765.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值