FPS游戏漫谈优化包体传输

2024-02-26 09:44

本文主要是介绍FPS游戏漫谈优化包体传输,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在游戏服务器的部署环境中,机房的网络带宽都是有限制的。如果通信传输的数据总量太大,会挤占带宽甚至达到带宽上限,影响正常消息发送。另外,如果包体太大,在弱网环境下的通信质量会变差,更容易发生丢包重传和延迟,而且大包对于截包和查找问题也不方便。因此我们需要对消息通信做优化,减少包体的大小和数量,进而减小传输的数据总量。

缩减包体大小
我们很容易理解包体太大对网络通信造成的负面影响。因为一个完整的数据包在通信协议底层也是拆成多个小包发送,在弱网环境下,每个小包都有可能发生丢包重传和延迟,叠加起来会让整个完整数据包也更容易出现问题。另外有实际经历的人会很理解从一大堆冗余数据里查找目标字段时的痛苦。

缩减包体大小的第一个方法是只传必要字段。

首先是使用前端静态表。策划配置的数据一般称为静态表,与存储玩家数据的动态表不同,静态表是只读不可修改的。建议对静态表的数据归类,数值类的放在服务端,显示类的放在客户端,这样好处是很多数据前端可以直接从前端静态表读取,不再依赖后端传输,后端通常只需要传一个id作为索引。

对于前后端静态数据如何划分是一个值得权衡的问题。通常来说,衡量的标准有两个维度:与前后端业务的相关性,以及该数据占用空间的大小。例如,数值类的数据与服务端计算强相关,因此适合放在服务端;而描述性的文字占用字节多,不宜通过服务端传输,因此放在客户端;图片和动画资源路径类的数据与客户端业务强相关,也放在客户端。

不过有时候前后端静态数据的划分界限并不那么清晰,这时候还需要结合其他要素做判断。例如,一个数值类的数据前后端都用到了,那么是否还需要放在回包消息中由后端传输呢?我们可以提前预判这个数据在将来变化的可能性大小,如果不太可能变化,那么就让前端直接从前端静态表中读取;反之,如果变化可能性很大,那么还是让前端从后端回包中获取该数据。这样做的好处是,模块上线后一旦需要数值调整,可以只需要后端对静态表做一次热更新,而前端不需要发额外的热更新,前者比后者对玩家的影响更小。

我们可以将前端静态表设计为后端静态表数据的超集,这样在选择本地读取还是后端传输时有更大的灵活性。

其次是优化消息结构体,减少冗余字段。例如下面的json数据用于描述玩家的功能列表中有哪些已开启:

“functionList”: [
{
“functionId”: 1
“isOpen”: true
},
{
“fuctionId”: 2
“isOpen”: false
},

]
1
2
3
4
5
6
7
8
9
10
11
可以将已开启功能的id直接放到一个列表中,精简为如下结构:

“openFunctionList”: [
1, 3, 4, …
]
1
2
3
任何一个合格的游戏服务器程序员都应该追求简单有效的协议模型。

缩减包体大小的第二个方法是对传输数据做压缩。

一般建议对传输数据开启压缩。常用的压缩算法有Gzip、LZ4、Deflate等。就拿最常见的Gzip来说,通常情况下它可以将json数据压缩到原来的1/3到1/2大小,用时仅为毫秒级别。不过压缩率也受到数据大小和数据内容的影响。如果原始数据中的内容重复率很高,数据量较大,那么压缩效果会更好,因为Gzip底层是基于LZ77算法和霍夫曼编码,对重复率高的内容做编码上的优化。

注意,某些二进制通信协议(如Msgpack)本身已对数据做了压缩,那么不要重复做压缩了,重复压缩并不能继续减小包体大小,反而会带来额外的性能开销。

减少推送消息的数量
这是从另一个维度减小传输数据总量。

首先是只推送给必要的对象。推送范围的判断有时候很容易,因为有时范围是固定的,例如一个游戏中的聊天室,每个玩家加入聊天室就默认进入了一个推送消息组,所有的聊天消息都会实时推送到这个消息组里的每个人。通常我们不提倡设立一个超大的聊天室,因为聊天消息的数量与参与人数是O(n^2)的关系,当人数增加时,聊天消息数量会迅速增加直至爆炸。

推送范围有时候又是灵活多变的,典型的例如一个MMORPG中的超大地图上的消息推送,这时就要用到通常所说的AOI算法,只推送给当前对象周围一定范围内的玩家。常用的AOI算法就是基于九宫格模型,还有的游戏会根据业务特点做模型优化,例如我曾经分享过重返帝国使用的梯形模型。
在这里插入图片描述

其次是降低推送的频率。例如,在重返帝国的游戏中,大地图上军队的血量并不需要在每次变化时都推送,可以每隔一小段时间做一次推送,这么细节的内容即使减少推送频率,也不会对玩家体验有明显的变化。降低推送频率的做法也叫推送裁剪。

对包体大小的权衡
要注意的是,包体并非越小越好,必要时还需要合并小包。在笔者的上一篇文章中,我们讲过大量小包的出现会降低网络带宽的利用率,同时导致弱网环境下的传输质量变差。针对这种情况,我们在不影响客户端表现的前提下,在业务层做多个小包的合并。例如,一个由服务端驱动的战斗一帧内向客户端推送了如下三条战报:

A|move|timestamp
B|att|C|timestamp
C|die|timestamp
1
2
3
原本是每产生一条新战报都推送,我们可以优化成服务器运行一帧后再合并推送:

A|move;B|att|C;C|die;timestamp
1
由于客户端也是逐帧渲染,原本一帧以内不同时刻到达客户端的小包实际也是在帧末统一处理和渲染,所以这样的改动不会对玩家体验有任何影响,但是网络传输的效率得到显著提升。

有时候我们也需要分拆大包。例如,在玩家登录游戏时,通常需要向客户端传递大量数据,有人会选择把这些数据全部放在一个接口中,例如:

登录大接口:
玩家基本信息(名字、等级、经验)
聊天历史消息
主城信息
好友信息
1
2
3
4
5
但是我们有充分理由不这么做,而是按功能拆分成多个接口,登录时依次调用它们:

接口一:玩家基本信息(名字、等级、经验)
接口二:聊天历史消息
接口三:主城信息
接口四:好友信息
1
2
3
4
因为大接口有如下四个缺点:

延迟更高,弱网环境下接口超时情况更多。
查看分析回包数据困难。
接口功能定位模糊,复用成本高。
更容易出错,出错时会卡住关键逻辑(登录)。
小结
总之,优化包体传输对于减小带宽占用、提升通信质量都有明显的好处。我们应该从缩减包体大小、减少推送消息数量两个角度做优化。对于包体大小要做适当的权衡,对于大量小包我们需要做必要的合并,而对于大接口我们应该做合理分拆,让每个接口独立做专门的事情。
————————————————

这篇关于FPS游戏漫谈优化包体传输的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/748449

相关文章

Linux中压缩、网络传输与系统监控工具的使用完整指南

《Linux中压缩、网络传输与系统监控工具的使用完整指南》在Linux系统管理中,压缩与传输工具是数据备份和远程协作的桥梁,而系统监控工具则是保障服务器稳定运行的眼睛,下面小编就来和大家详细介绍一下它... 目录引言一、压缩与解压:数据存储与传输的优化核心1. zip/unzip:通用压缩格式的便捷操作2.

MyBatisPlus如何优化千万级数据的CRUD

《MyBatisPlus如何优化千万级数据的CRUD》最近负责的一个项目,数据库表量级破千万,每次执行CRUD都像走钢丝,稍有不慎就引起数据库报警,本文就结合这个项目的实战经验,聊聊MyBatisPl... 目录背景一、MyBATis Plus 简介二、千万级数据的挑战三、优化 CRUD 的关键策略1. 查

Python实例题之pygame开发打飞机游戏实例代码

《Python实例题之pygame开发打飞机游戏实例代码》对于python的学习者,能够写出一个飞机大战的程序代码,是不是感觉到非常的开心,:本文主要介绍Python实例题之pygame开发打飞机... 目录题目pygame-aircraft-game使用 Pygame 开发的打飞机游戏脚本代码解释初始化部

SpringBoot中HTTP连接池的配置与优化

《SpringBoot中HTTP连接池的配置与优化》这篇文章主要为大家详细介绍了SpringBoot中HTTP连接池的配置与优化的相关知识,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一... 目录一、HTTP连接池的核心价值二、Spring Boot集成方案方案1:Apache HttpCl

PyTorch高级特性与性能优化方式

《PyTorch高级特性与性能优化方式》:本文主要介绍PyTorch高级特性与性能优化方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、自动化机制1.自动微分机制2.动态计算图二、性能优化1.内存管理2.GPU加速3.多GPU训练三、分布式训练1.分布式数据

MySQL中like模糊查询的优化方案

《MySQL中like模糊查询的优化方案》在MySQL中,like模糊查询是一种常用的查询方式,但在某些情况下可能会导致性能问题,本文将介绍八种优化MySQL中like模糊查询的方法,需要的朋友可以参... 目录1. 避免以通配符开头的查询2. 使用全文索引(Full-text Index)3. 使用前缀索

C#实现高性能Excel百万数据导出优化实战指南

《C#实现高性能Excel百万数据导出优化实战指南》在日常工作中,Excel数据导出是一个常见的需求,然而,当数据量较大时,性能和内存问题往往会成为限制导出效率的瓶颈,下面我们看看C#如何结合EPPl... 目录一、技术方案核心对比二、各方案选型建议三、性能对比数据四、核心代码实现1. MiniExcel

Python开发文字版随机事件游戏的项目实例

《Python开发文字版随机事件游戏的项目实例》随机事件游戏是一种通过生成不可预测的事件来增强游戏体验的类型,在这篇博文中,我们将使用Python开发一款文字版随机事件游戏,通过这个项目,读者不仅能够... 目录项目概述2.1 游戏概念2.2 游戏特色2.3 目标玩家群体技术选择与环境准备3.1 开发环境3

MySQL索引的优化之LIKE模糊查询功能实现

《MySQL索引的优化之LIKE模糊查询功能实现》:本文主要介绍MySQL索引的优化之LIKE模糊查询功能实现,本文通过示例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录一、前缀匹配优化二、后缀匹配优化三、中间匹配优化四、覆盖索引优化五、减少查询范围六、避免通配符开头七、使用外部搜索引擎八、分

Python通过模块化开发优化代码的技巧分享

《Python通过模块化开发优化代码的技巧分享》模块化开发就是把代码拆成一个个“零件”,该封装封装,该拆分拆分,下面小编就来和大家简单聊聊python如何用模块化开发进行代码优化吧... 目录什么是模块化开发如何拆分代码改进版:拆分成模块让模块更强大:使用 __init__.py你一定会遇到的问题模www.