从客户端开发的角度全面看待网络通信模块的设计,最终目标即为了营造最丝滑的用户体验,有些操作甚至是模拟的,除非迫不得已,否则我们完全不想让用户感知到任何的网络波动。
一,短链接
应付非及时性要求高的情况,通常用来在启动游戏时进行获取配置和更新资源。
协议选择
http或者https,后者更安全。
数据传输格式
一般采用json,重要的信息,如连接地址则需要加密。
- 配置信息(web服务器)渠道,平台类型(IOS、Android)资源更新地址。
- 资源服务器(web服务器)。
- 登陆服务器(中心服概念,再通过负载均衡机制分配游戏逻辑服务器)。
- 游戏服务器。
资源服务器
通常需要增加一个CDN转发服务,特别是做全球服(付费的要好一些(也有免费的))。
资源更新
采用md5码校验,受网络波动的影响。
- 需要重新下载
- 所以资源包粒度需要优化,资源尽可能在理想的范围波动,比如2M。
- 太大,重新下载时带宽资源浪费。
- 过小,则网络连接数量过多,IO频繁。通常在网络状态良好时,文件数量过多,导致下载耗时过长。
- 为了更好的用户体验,下载进度条可以采用模拟的形式(普遍的做法)。
- 断点续传(一般不需要)
断线处理
- 登录请求:定义单次超时10s,重复请求3次即为网络失败。
- 资源下载:定义下载失败次数,比如10次。
二,长链接
适用对即时性要求高的情况,资源占用的比短链接多。
消息队列
由于网络通信线程是独立线程,有可能收发时机处于逻辑线程的同一帧,所以收到消息后可以在下一帧进行广播。
数据压缩
- xml,json,cson,yaml,toml 文本。
- protobuf 字节流,用应以好的格式来编码解码,相当于加了一个中间层。
- 也有自定义自解析的文本格式,比XML和Json都要小一些。
通信机制:WebSocket
- 兼容Web平台。
- 可以采用两种格式:ws://或者wss://,后者更安全。
- 和一般Socket的区别是连接时用http开始,后来也是标准通信,吞吐量差不多。
通信机制:Socket
核心问题在于分包粘包处理(TCP网络通讯如何解决分包粘包问题 https://blog.csdn.net/sweettool/article/details/77018506)。
安全
- Token令牌:服务器用来做登录和订单的校验。
- Wss:通过ssl证书验证(非对称加密机制)。
- 自定义:客户端和服务端需要保持一致的数据加密解密算法。
实时性
- 弱交互
- 强交互
- 状态同步:策略类,如棋牌。
- 帧同步:动作类,如moba/fps/tps。
心跳机制(弱交互和状态同步)
- 心跳时长设置 区分大厅场景和战斗场景,战斗5秒一次心跳?超时40秒?也有同学说,如果做海外市场可以设置为2分钟一次心跳(这就有点夸张了,在某种测试场景下可以这么做)。
- 不得不提的是,传输时长遵循我们物理世界的规律,所以服务器通常布局在合适的地理位置,或者多点布局。
断网与弱网的处理机制(涉及不同的游戏类型)
- 断网重连:简单粗暴。
- 本地模拟:后台仍然在接收数据,切换到前台时,使用缓存数据,执行类似断网重连式的刷新。
- 静默重连:通常重连后能回到之前的游戏状态的话,静默处理即可。
- 显式提醒:回不到之前的游戏状态,比如战斗结束。
客户端踢人
- 弱网监测机制(心跳) 分级。
- 前后台切换(记录后台时长),根据时长做区分 客户端模拟还是重连服务器(从登录开始)。
服务端踢人
- 用户行为异常,如频繁请求。
- 数据异常,如通信包数据篡改。
- 进入维护状态。
三,举例
一个网页开房间游戏的断线重连机制设计。
四,最后
起决定性的当然是用户自身的网络条件和设备性能了。毕竟网络环境(网际网络服务供应商(ISP)架设的路由设定,用户的网络连接带宽套餐服务,以及后台下载线程的多寡)我们是控制不了的,我们也不能强制用户专门为我们的游戏升级网络与计算资源,而且极端情况还要考虑到天灾人祸,所以完全保证完美的网络体验是不现实的,但是可以尽力做到最好。
五,延伸
- TCP中已有SO_KEEPALIVE选项,为什么还要在应用层加入心跳包机制?? https://www.zhihu.com/question/40602902
- ISO 七层/五层模型
- 物理层传输媒介:光缆(2019年已超过140万公里)
- 光缆的一般结构