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
因为大接口有如下四个缺点:

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2809898.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Oracle EBS GL 外币折算逻辑

背景 由于公司财务在10月份期间某汇率维护错误,导致帐套折算以后并合传送至合并帐套生成合并日记帐凭证的借贷金额特别大,但是财务核对的科目余额有没有问题,始终觉得合并日记帐生成会计分发有问题,需要我们给出外币折算逻辑。 基础设置 汇率 Path: GL->设置->币种-&…

pytest-配置项目不同环境URL

pytest自动化中,在不同环境进行测试,可以将项目中的url单独抽取出来,通过pytest.ini配置文件实现(类似postman中的“Environments”) 使用步骤: 1)安装pytest-base-url插件 pytest-base-url …

博客阿里云服务器2024年最新优惠价格表,61元起

博客 阿里云服务器2024年最新优惠价表,轻量级应用服务器61元起,云服务器99元起 01-30 第591章 2024年阿里云服务器最新优惠价是多少? 阿里云服务器的租用价格在不同时期是不同的。 进入2024年,阿里云服务器的优惠价格也发生了…

好书推荐丨细说Python编程:从入门到科学计算

文章目录 写在前面Python简介推荐图书内容简介编辑推荐作者简介 推荐理由粉丝福利写在最后 写在前面 本期博主给大家推荐一本Python基础入门的全新正版书籍,对Python、机器学习、人工智能感兴趣的小伙伴们快来看看吧~ Python简介 Python 是一种广泛使用的高级、解…

Git Windows安装教程

Git的下载 去 Git 官网下载对应系统的软件了,下载地址为 git-scm.com 或者 gitforwindows.org git-scm 是 Git 的官方,里面有不同系统不同平台的安装包和源代码gitforwindows.org 里只有 windows 系统的安装包 安装 使用许可声明 选择安装目录 选择安…

深入理解Java中的Reader类:一步步剖析

咦咦咦,各位小可爱,我是你们的好伙伴——bug菌,今天又来给大家普及Java SE相关知识点了,别躲起来啊,听我讲干货还不快点赞,赞多了我就有动力讲得更嗨啦!所以呀,养成先点赞后阅读的好…

回归预测 | Matlab实现CPO-HKELM冠豪猪算法优化混合核极限学习机多变量回归预测

回归预测 | Matlab实现CPO-HKELM冠豪猪算法优化混合核极限学习机多变量回归预测 目录 回归预测 | Matlab实现CPO-HKELM冠豪猪算法优化混合核极限学习机多变量回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现CPO-HKELM冠豪猪算法优化混合核极限学习机…

我耀学IT—day03-徽章及进度条

一、Bootstrap5 信息提示框 Bootstrap 5 可以很容易实现信息提示框。 提示框可以使用 .alert 类, 后面加上 .alert-success, .alert-info, .alert-warning, .alert-danger, .alert-primary, .alert-secondary, .alert-light 或 .alert-dark 类来实现: 例: <div class&quo…

IO进程线程复习:进程线程

1.进程的创建 #include<myhead.h>int main(int argc, const char *argv[]) {printf("hello world\n");//父进程执行的内容int num520;//在父进程中定义的变量pid_t pidfork();//创建子进程if(pid>0){while(1){printf("我是父进程&#xff0c;num%d\n&…

[第一章 web入门]SQL注入-1 题目分析与详解

一、题目简介&#xff1a; 题目来源&#xff1a;BUUCTF网址 题目介绍如图&#xff1a;获取flag值。 二、解题思路&#xff1a; 首先看到题目主页面有一段文字&#xff0c;貌似没有什么作用&#xff0c;我们先使用HackBar导入URL。 我们发现?id1&#xff0c;可知这是一个很基…

小猫咪不喝水怎么办?主食冻干、主食罐头喂养从饮食上给猫咪补水

小猫咪不喝水怎么办&#xff1f;它们会不会在感到口渴、缺水时自己去寻找水喝呢&#xff1f;猫的祖先是来自沙漠的猫科动物&#xff0c;在沙漠几乎找不到水源&#xff0c;因此它们进化出了“低渴感”&#xff0c;并且它们的肾脏进化出了浓缩水分再吸收的功能&#xff0c;使得猫…

安全测试工具之nmap使用指南

文章目录 一、前言二、简介三、使用示例&#xff08;一&#xff09;常用命令&#xff08;二&#xff09;主机存活检测&#xff08;三&#xff09;端口探测&#xff08;四&#xff09;服务识别&#xff08;五&#xff09;操作系统识别 三、其它 一、前言 当我们在构建环境或排查…

怎么使用Python轻松打造淘宝主图视频生成神器

目录 一、引言 二、淘宝主图视频的重要性 三、Python打造淘宝主图视频生成神器的步骤 1. 准备工作 2. 收集素材 3. 制作视频 4. 调整和优化 5. 上传至淘宝 四、案例分享 五、总结 一、引言 随着电子商务的飞速发展&#xff0c;淘宝作为中国最大的网络购物平台之一&am…

【非递归版】归并排序算法(2)

目录 MergeSortNonR归并排序 非递归&归并排序VS快速排序 整体思想 图解分析​ 代码实现 时间复杂度 归并排序在硬盘上的应用&#xff08;外排序&#xff09; MergeSortNonR归并排序 前面的快速排序的非递归实现&#xff0c;我们借助栈实现。这里我们能否也借助栈去…

Qt QWiget 实现简约美观的加载动画 第三季

&#x1f603; 第三季来啦 &#x1f603; 这是最终效果: 只有三个文件,可以直接编译运行 //main.cpp #include "LoadingAnimWidget.h" #include <QApplication> #include <QVBoxLayout> #include <QGridLayout> int main(int argc, char *argv[]…

一款.NET下 WPF UI框架介绍

WPF开源的UI框架有很多,如HandyControl、MahApps.Metro、Xceed Extended WPF Toolkit™、Modern UI for WPF (MUI)、Layui-WPF、MaterialDesignInXamlToolkit、等等&#xff0c;今天小编带大家认识一款比较常用的kaiyuanUI---WPF UI&#xff0c;这款ui框架美观现代化&#xff0…

使用单一ASM-HEMT模型实现从X波段到Ka波段精确的GaN HEMT非线性仿真

来源&#xff1a;Accurate Nonlinear GaN HEMT Simulations from X- to Ka-Band using a Single ASM-HEMT Model 摘要&#xff1a;本文首次研究了ASM-HEMT模型在宽频带范围内的大信号准确性。在10、20和30 GHz的频率下&#xff0c;通过测量和模拟功率扫描进行了比较。在相同的频…

端口映射教程?

端口映射是一种网络技术&#xff0c;用于在公网与内网之间建立网络连接。在互联网中&#xff0c;设备通过IP地址和端口号进行通信&#xff0c;而内网中的设备通常被分配了私有IP地址&#xff0c;无法直接被公网访问。端口映射可以将公网的请求转发到内网中的设备&#xff0c;从…

第7.1章:StarRocks性能调优——查询分析

目录 一、查看查询计划 1.1 概述 1.2 查询计划树 1.3 查看查询计划的命令 1.3 查看查询计划 二、查看查询Profile 2.1 启用 Query Profile 2.2 获取 Query Profile 2.3 Query Profile结构与详细指标 2.3.1 Query Profile的结构 2.3.2 Query Profile的合并策略 2.…

汇总利用YOLO8训练遇到的报错和解决方案(包含训练过程中验证阶段报错、精度报错、损失为Nan、不打印GFLOPs)

一、本文介绍 本文为专栏内读者和我个人在训练YOLOv8时遇到的各种错误解决方案,你遇到的问题本文基本上都能够解决,同时本文的内容为持续更新,定期汇总大家遇到的问题已经一些常见的问题答案,目前包含的问题已经解决方法汇总如下图所示。 专栏目录:YOLOv8改进有效系列目录…