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