浅谈手游程序基本坑

浅谈手游程序基本坑


当下国内的游戏公司应该都必定程度上参和到手游市场了的吧?不少的游戏开发人员都是以前页游过来的,在程序设计和功能实现上都延续了页游的那一套思路方法,原则上来是对功能实现上并不存在任何的问题。可是细细分析下里面是存在着一些点能够被优化或者说直接是坑。前端

前奏

我我的经历过三个手游项目,两个卡牌一个MMO,接下来提出来的点多是会傻逼。可是我明确的知道不少项目都是比较随意的去对待这些问题的,因此才有了我一系列的小文章来论述这些问题。但愿你们在开新项目的时候能够尽量的避开这些底层设计控制的坑。后端

顾名思义手机游戏,绝大多数的状况下都是运行在手机环境下的。手机对比电脑不足之处实在是太多。这边就围绕着接下来的问题提出几个关注点:缓存

  1. 手机的电量是宝贵的
  2. 手机的发热量是要被控制的
  3. 手机的流量是宝贵的
  4. 手机网络的延迟是不可控的
  5. 手机网络是不稳定的

断线重连(客户端)

由于手机网络的不稳定性,致使手机游戏的频繁的断开、重连网络是很是常见的现象。在页游时代这个行为是一个F5(刷新)就搞定的事情,可是在手机时代这个方案明显行不通。因此咱们有了下面这个话题:服务器

在开始这个话题以前我用wireshark工具抓包了以下几个游戏并简单观察其机制(不必定是对的)网络

  1. 《皇室战争》 tcp+udp协议混合使用,主界面的操做流程是由tcp socket来控制传输的,战斗过程当中是udp协议进行数据的传输的。在网络断开的状况下就是从新走登陆流程。
  2. 《王者荣耀》 跟《皇室战争》的传输模式基本上是同样的也是tcp和udp联合使用。
  3. 《暗黑破坏神2》tcp协议,由于当下用的协议就是tcp因此着重研究了该游戏的网络重连。

以打副本为例子:app

  1. 若是是进入游戏后本身主动断开网络,能够继续参与游戏的战斗,直到副本结算时会弹出网络异常请从新链接,点击重连会对数据进行重发,过了5秒后若是尚未成功又弹出该界面。若是这个时候网络链接上去是能够按照正常的流程参与结算的。
  2. 在无感知的状况下断开前端网络(手机不断网,把路由器断网):点击打副本进不去。若是在副本里面的话能够继续进行战斗知道结算。一样的会出现第1种那样的状况。
  3. 前面2中状况说的都是服务器已经断开链接的状况,从抓包分析上看,服务器应该是3次心跳都没有收到的状况下回主动断开与前端的socket链接。 若是在这三次心跳时间内重现网络链接上去,其实先后端都认为没有发生过网络异常。能够按照正常的流程进行结算。
  4. 若是网络链接失败的状况下,下次再网络情况良好的地方还能够正常的结算。
    .....

总结:socket

内容表现很是的多,我单测试这个就用了一个上午的时间,这边也不浪费你们的时间直接来看结论和合理的设计:tcp

  1. 客户端必须作对出去包的缓存处理。 以备用网络链接断开点击重连时请求数据还存在。
  2. 在网络链接过程当中,若是socket一直没有断开(前端的没有断),前端仍然能够往socket发送数据,在第一次点击重连时能够再原socket上发送数据,若是第二次点击重连时就应该手动把旧的socket断开,新创建一条根服务端的socket并把缓存数据发送出去。
  3. 无论怎么什么状况下,若是手机主动获得了socket断开的回调,就应该进入自动重连的模式,若是有重要包应该直接弹窗,不然的话就后台本身重连,重连后当即把缓存的数据发送出去。
  4. 服务端通常会在屡次心跳未收到的状况下主动断开socket,以避免形成过多的“僵尸”玩家存在。
  5. 服务端作数据缓存操做,由于有可能前端发过来多个请求结算,这个时候第二个包确定是结算失败的。因此须要从缓存中把上一次结算的时间返回给前端。

网络中断(服务端)

分析下网络中断的状态和行为能够分为以下四种:工具

  1. 玩家主动退出游戏,网络断开
  2. 玩家kill掉游戏进程,网络断开
  3. 玩家网络情况糟糕频繁的掉线重连
  4. 接电话、钻地铁、回复消息等游戏进程进入后台的网络断开

从四种断网方式中能够判定出玩家的接下来行为:性能

  1. 前两种行为若是要继续游戏必须从新登陆游戏
  2. 后两种行为切回游戏界面就能够继续游戏

对于服务器来讲,除了第一种状态下服务器知道玩家是下线状况外,其余的三种状态服务器是没法区分的,由于对于服务器来讲都没有主动收到前端的fin包(网络中断)的包,这也就是为何基本上全部的游戏都有心跳包的缘由,其实就是用来界定网络是否还存在的状况。

在传统的页游中,主要发生了断线行为都是直接把数据存档,内存数据消除。听起来好像没有问题,可是回去分析玩家行为时会发现,其实后两种行为在切回游戏界面时是能够继续进行游戏的,这个时候若是把数据dump有两种状况:

  1. 内存数据直接丢失,可能形成玩家接下来的数据就异常,好比说在作刷怪任务时,可能中途有数据直接传到服务器来保存,可是由于只是结算的时候用,因此也不会设计到入库,这样的状况就比较糟糕了,玩家从新回来的时候数据就丢了,可是对于前端来讲仍是正常的...
  2. 频繁的dump数据到磁盘自己是比较耗费性能,并且也是无心义的。好比说玩家在座地铁,可能一条线上断网20次,那就是20次的从磁盘加载数据到内存,再从内存dump数据到磁盘。

其余的细节就不追究仍是直接来看结论:

  1. 状态
    对于玩家进程行为加多一种状态标记:dump,因此玩家最起码有以下三种状态:(在实际的项目中每每是远大于这三种状态的)
    1. offline 离线状态
    2. online 在线状态
    3. dump 数据缓存状态(玩家下线了,可是数据还留在缓存中的状态若是玩家从新登陆的话只须要把链接从新指向下就好)
  2. 临时数据

    手游状况比较特殊,基本上能够说全部的数据都必需要入库处理操做好点。最容易联想到的现象就是别人早上打开游戏,而后home键到后台,晚上再继续游戏,不入库的话根本掌握不住这个时间点。临时缓存数据也须要入库操做,通常会加上时效性。

  3. 服务器的重连

    若是仅仅是经过socket来进行标记,服务器是没法判断是不是重连。也就是说走的路线都是重登录了。因此这个时候前端跟服务器重连时必须给服务器带过里标记: 重连、登陆标记。服务器根据这两个标记刷新数据、推送数据。(好比重连不须要额外推送红点和数据,重登录的话可能须要把上一把的临时数据的存档清楚)

  4. 先后端数据同步

    在后面2中状况下(从新切回主界面),若是涉及到跨天或者活动相关的推送时是会比较尴尬的。好比说:跨天刷新数据,本来是要把缓存数据都清楚而后从新获取,可是由于进入了后台得不到cpu使用权就丢失了跨天的回调,致使久数据没法刷新;活动推送若是在登陆状态下回直接推送、重登录也会出发推送,可是对于重连通常不会触发推送这个点也是比较尴尬的。因此也有一些作法是作成进入后台xx小时,同时重连的时候跟打开app的时间不在同一天都会触发游戏从新登陆的(kill app 重连)。

流量

流量是人民币,若是不珍惜也会对留存形成必定的影响哦。

由于手游开发人员广泛来源于页游,页游这块网络的不须要太多的考虑的。因此前端的缓存作的是相对来讲比较少,都是直接跟服务器请求数据的,可是再手游状况下听起来就以为不怎么妥....

废话很少说直接说结论:

  1. 合并数据包

    对数据进行合并操做,在网络出口处,若是在一个瞬间又多个包同时推送给同一个玩家须要对包进行合并操做。 一个tcp的包头最小20字节呀(很大),因此能合并就合并下吧。

  2. 数据前端缓存

    在协议商定时额外的带多一个标记位,用于指定是获取更新数据呢仍是获取所有数据。(建议本地有缓存的状况下都作更新数据处理),对于切tab操做(手残党最喜欢作),尽量的避免反复请求。 切记:别作成每次打开界面都跟服务器拿数据。

  3. 分批按量发送

    数据分批份量来推送,避免推送大数据,最典型的表明就是排行榜、拍卖行。

  4. 数据扁平化设计

    例如把一个int数据拆出来表示多个字段的意义。

  5. 数据压缩

    对于大于xx字节的数据包进行压缩。

电量和发热量

当前市场上不少游戏插着充电线电量都仍是在减小的。也有游戏玩一会手机就成为了暖手炉的。
这两个点影响流失的比率仍是比较高的。我就卸载不少这样的游戏。想一想你的手机本来充满电用一天的,可是如今玩了一会游戏就要自动关机了。想一想你用你的双手握着一个暖炉的时候是怎么样感受....

那么怎么来下降这两个点呢:(由于我主要是后端,这个点可能点的比较虚)

  1. 减小cpu的使用率,能够从内存换cpu的角度上去衡量下。
  2. 减小GPU的使用,前端gpu的渲染很是耗电。
  3. 减小网络应答,这个对比前面两个能够小到忽略。由于网络也是io对cpu也是比较的耗的。

总结

这里的结论可能并不必定都是最好的,也可能考虑到的点尚未那么全面。欢迎前来拍砖...

(本文的结论基本上都是通过线上测试验证过的,并非本身臆想天开得来的)

相关文章
相关标签/搜索