当前位置: 首页 > article >正文

Games104——网络游戏的架构基础

这里写目录标题

多人网络游戏面临的挑战

  1. 保证每个用户事件的一致性
  2. 网络延迟和丢包
  3. 反作弊反信息泄露
  4. 复杂的设备,快速进行热更新迭代
  5. 复杂度高
    在这里插入图片描述

网络协议

OSI模型

在这里插入图片描述

Socket

通过一个简单的接口与另外一台机器建立连接就可以持续不断的传输数据
在这里插入图片描述

TCP/IP协议

特点:连接稳定、流量控制、包头长,保证信息的一致性
在这里插入图片描述
TCP的拥塞控制
在这里插入图片描述
对于对时间不太敏感但对稳定性有要求的游戏适合用TCP

UDP协议

端到端的协议
特点:不需要建立长时间的链接、不需要流量控制、包头轻、传播很快、但稳定性不行容易传达不到
在这里插入图片描述

在不稳定的网络情况下要求响应速度块适合用UDP,如吃鸡类

基于UDP的可靠连接

对于大型MMO不会使用单一协议,哪个适合用那个,游戏开发很多时候不会使用原生态协议
在这里插入图片描述

自动重复的要求

  • Stop and Wait ARQ
    等待ACK包到达后再去发下一个
    在这里插入图片描述
  • Go Back N ARQ
    发现一个包丢失后将窗口中的重新传一遍
    在这里插入图片描述
  • 选择重传ARQ
    告诉哪个包没有传到,重传没传到的那个包即可
    在这里插入图片描述
  • Forward Error Correction FEC
    在这里插入图片描述

Forward Error Correction FEC

XOR-FEC(异或运算)

在这里插入图片描述
在这里插入图片描述
如果丢失任何数据包,可以使用其他四个数据包进行恢复。
连续数据中只能丢失一个数据包。如果A和B同时丢失,算法将无法恢复。

不适用于丢包率高的情况

Reed-Solomon Codes

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

可以通过矩阵计算得到丢掉的数据
丢包率高的情况(比如移动端)也可以保证传输数据
在这里插入图片描述
可以根据具体需要DIY传输协议

时钟同步&RPC

对战游戏的重点就是要将时钟对准

RTT

我发一个包给对方多久能得到一个回包
在这里插入图片描述
RTT是自己写的,Ping更偏向底层

如何去对时间?

NTP

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
默认上行下行的时间是对等的,但事实上上下两路不一定是对等的,所以该算法不会很准确
在波动的网络下无法对准时间,只能推测

客户端和服务端建立连接时第一时间就要把钟对好
在这里插入图片描述

在这里插入图片描述

  1. 把NTP算法先跑一遍,算出来客户端时间和服务端时间的差别
  2. 调整客户端的时钟,因为网络会波动,所以多做几次NTP算法,记录每次RTT
  3. 去掉RTT比平均值高的值,再做一次平均,再用这个平均值对钟进行调整

RPC

对程序员而言在服务器和客户端之间网络传输会有以下的困难:
运行用不同语言编写
过程使用不同大小的数据类型
使用不同的字节顺序(字节序)
以不同的方式表示浮点数
具有不同的数据对齐要求
在这里插入图片描述
在这里插入图片描述
RPC让程序员不需要定义复杂的网络报体结构,从而专注的写游戏逻辑,只需要传几个参数即可

Stubs

相当于票据存根
在这里插入图片描述
Stubs Compiler读取 lDL 声明,并生成两个 stub
服务器程序员实现服务的程序,并将其与服务器端的stub链接起来。
客户端程序员实现客户端程序并将其与客户端的stubs链接起来
subs管理客户端和服务器之间远程通信的所有细节。

网络拓扑

P2P

早期使用的网络架构,研发商不需要维护服务器
在这里插入图片描述

Dedicated Server

在服务器端维护一个游戏世界,由研发商提供
在这里插入图片描述

允许不同地区的玩家在服务器之间建立高速的连接
在这里插入图片描述

快照同步

早期使用
客户端把自己的输入发给服务器,服务器把整个游戏世界的状态生成一个快照,然后把快照发给所有的客户端
保证了状态的一致性
在这里插入图片描述
服务端和客户端之间的帧率不同,快照生成的算力消耗大,所以使用Delta
在这里插入图片描述

缺点:快照数据量大,不适合用户数据量大的情况
客户端没有进行计算,浪费了客户端的算力

帧同步

服务器:信息的同步汇总转发

Initialization

初始化游戏内核心数据,保证局内数据高度一致化
服务器获取到所有客户端的输入,并将所有客户端的输入再发放给每个客户端,但最慢的用户会拖慢所有的进程
在这里插入图片描述
在这里插入图片描述
设置一个上限,如果有客户端在时间内没有输入则直接舍弃,但会产生一些潜在的bug和用户输入无效的问题
在这里插入图片描述
难点:要构建一个确定性的游戏世界
在这里插入图片描述
如何解决

  • 保证浮点数的高度一致性
    在这里插入图片描述
  • 保证随机数的确定性
    在这里插入图片描述
    在这里插入图片描述

Lag and Delay

无法规避网络抖动就可以使用buffer
在各个节点catch很多的数据,在本地网络抖动时smooth,以达成观看时稳定的效果
解决网络延迟和抖动的问题
在这里插入图片描述

将逻辑帧和渲染帧分割开来,画面不会抖动
在这里插入图片描述

断线重连

断线重连时可以根据客户端留存的快照减少断线重连时产生的差距,方便追上
在这里插入图片描述
服务端会在几个关键帧进行快照,当玩家过长时间断线时可以根据服务端的快照,帮助setup游戏的状态
在这里插入图片描述
另外一个重要的应用场景是观战
在这里插入图片描述
在这里插入图片描述
基于帧同步的机制可以拓展出这些游戏玩法

反作弊

投票机制
每隔一段时间每个客户发送一个校验码,如果有一个客户的校验码有误则将其踢掉
在这里插入图片描述
帧同步的特点是在客户端可以获取到局内所有的状态,游玩时使用插件就可以获取到这些状态,但现在的游戏会采取一些方法来规避这些问题

优点:可以做一些打击状态清晰的对抗,方便做游戏录屏
缺点:保持一致性很难

状态同步

同步用户的状态信息,如关键性的爆炸,死亡等
每一个玩家提供部分的信息,Server去模拟一个世界,只把与每个用户相同的信息发给他,防作弊的能力好于帧同步

在这里插入图片描述

  • Authorized
    玩家本地客户端
  • Replicated
    在其他玩家客户端上1P的复制体

整个世界的核心逻辑都是由Server计算的
不要求所有的客户端保证确定性

状态同步面临的问题
在这里插入图片描述

客户端预测

先预测半个RTT的时间再加上一个Command frame的动作,等服务端数据回来之后再对齐,尽可能让移动平滑
在这里插入图片描述

服务端和解

如果在Server的时间点状态不一致,那必须根据Server的要求反向矫正行为
在这里插入图片描述
服务端需要一个RingBuffer存储过去几帧,出现了状态不一致的问题后RingBuffer之后的数据全部无效化重新算一遍
在这里插入图片描述

丢包问题

用RingBuffer把输入存储下来,在获取不到输入时采用最后一次输入的状态
在这里插入图片描述
状态同步适合网络和游戏业务比较复杂的情况

状态同步和帧同步的区别


http://www.kler.cn/a/529833.html

相关文章:

  • 使用真实 Elasticsearch 进行高级集成测试
  • 71.在 Vue 3 中使用 OpenLayers 实现按住 Shift 拖拽、旋转和缩放效果
  • model.eval() model.train()
  • 「全网最细 + 实战源码案例」设计模式——桥接模式
  • 深入理解Java引用传递
  • 【gRPC-gateway】option定义规则及HttpBody响应
  • Eigen::Tensor使用帮助
  • Qt常用控件 输入类控件
  • 文本复制兼容方案最佳实现落地。
  • Node.js常用知识
  • 在Qt中,slots 关键字有什么用?
  • GIt使用笔记大全
  • 面经-C语言——指针相关概念总结
  • 1. 【.NET Aspire 从入门到实战】--理论入门与环境搭建--引言
  • vue3-element-plus-admin 框架
  • 如何让跨域文件管控简单又高效
  • Hot100之贪心算法
  • 记录一下【Facebook 】expansionToken参数逆向
  • lstm代码解析1.1
  • Ubuntu 下 nginx-1.24.0 源码分析 main函数 — ngx_cdecl 宏
  • kamailio-Core 说明书 版本:Kamailio SIP Server v6.0.x(稳定版)
  • 效用曲线的三个实例
  • c++井字棋(单人对电脑:1.电脑随机下 2.电脑AI;3.双人对决)
  • Python Web框架比较:Flask与FastAPI的特性和应用场景
  • Mask R-CNN与YOLOv8的区别
  • 【HTML入门】Sublime Text 4与 Phpstorm