`
king_tt
  • 浏览: 2084535 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

从bug看《全民英雄》的接口设计

 
阅读更多
最近玩全民英雄,然后遇到一个bug,导致我一个账号卡死,不得不重玩新号。bug如下:
-------------------------------------------------
问题
-------------------------------------------------
在一个装备合成的引导,我点了合成,接着刚好断网,然后重连网络的时候发现合成的材料消失,可是依然处于合成的引导。这时候显然已经没法合成,而引导又是强制性的,因此没办法往下玩了。

-------------------------------------------------
猜测前端流程:
-------------------------------------------------
一开始,我猜测:可能是请求合成的时候前端自己移除了前端内存中的合成材料。而因为断网了,合成请求没发出,结果导致前端没材料,而引导却还没完成。
这个怎么验证呢?退出程序,重新登录。甚至改成换ipad玩都不行。因此并不只是前端移除了数据那么简单,材料在后端确实已经没了!

那么,我又想到了另一种可能:
他的合成和引导接口是分开的独立接口。怎么说呢?

-------------------------------------------------
猜测前端流程:
-------------------------------------------------
1、前端登录
2、收到当前引导到第几步,是否完成该步骤,是则执行3(不讨论否的情况)
3、发现有引导步骤没完成,则执行引导
4、玩家点击请求执行引导的功能
5、前端收到合成结果
6、前端判断当前是否有相关引导,是则执行7(不讨论否的情况)
7、前端请求后端记录新的引导状态

乍一看好像没啥问题,但实际你会很容易发现,其实在5、6、7任何一步出错或断网。都会导致扣了材料还没完成引导。

-------------------------------------------------
类似例子
-------------------------------------------------
这个问题其实我把它归类为“带状态的接口调用”,即一个接口的请求需要依赖上一个请求的接口。这种接口的设计很容易出bug,服务端应该记录好每个接口的状态,甚至对一些请求的状态做持久化。举个极端点的例子,不过这个例子比较明显,一般没人这么做!
比如:以普通RPG中合成神器为例,假设合成需要选择2个材料, 然后点击合成。如果这么设计这个接口:
1、当玩家选择第一个材料的时候,请求后端, 后端扣除并记录当前材料
2、当玩家选择第二个材料的时候,请求后端,后端扣除并记录当前材料
3、当玩家点击合成时,后端根据前面记录的两个材料 生成一个新装备给玩家
因为这个错误实在太明显,导致大家不会那么做。而其实这个问题和前面《全名英雄》的处理本质是一样的。只要断网,而后端没做好第1、2步请求的状态持久化,那么材料必定丢失。(如果有记录玩家选过那两个材料,那玩家还能继续点击合成直接第三个接口,而不至于材料被扣除却没合成)

-------------------------------------------------
简陋的解决方案
-------------------------------------------------
回到《全民英雄》那个例子,既然现在玩家是因为先请求和合成,成功合成装备并扣除了材料,然后断网才没请求到记录引导状态。那能不能换个顺序:玩家点击合成之后,先请求记录引导状态再请求合成。这样它如果中间出现断网,顶多就是下次连接的时候引导不见了,但不至于材料被扣除,也不会导致卡死在引导界面(因为更新引导状态已经请求过了,重新连接会获得下一步引导的状态)。这样确实是解决了BUG,但是这样玩家就缺少了一次引导,解决的也不是很彻底。

-------------------------------------------------
完善的解决方案
-------------------------------------------------
我们回想一下,刚刚说的“带状态的接口调用”,即一个接口的请求需要依赖上一个请求的接口。那其实,如果只请求一个独立接口,就不会有这种问题。那请求的应该是合成接口呢,还是引导接口呢?
个人认为,请求合成接口更合适。因为后端本来就有合成接口,只需要后端在合成的时候派发一个事件出去,让引导模块捕获这个事件,然后重置自己的引导状态就可以。这样还省一个接口请求,还节省你流量,多贴心啊!

欢迎大家讨论!
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics