游戏通讯方式

农药自从上线以来,依靠着强大的产品力以及腾讯的运营能力,在游戏市场上表现可谓是风生水起,根据第三方的调研数据显示,《王者荣耀》渗透率达到22.3%,用户规模达到2.01亿人,每日的日活跃用户(DAU)均值为5412.8万人。 如此可观的数据,令人十分钦佩。

当然了,作为技术人,更愿意从技术上了解去一些王者荣耀的实现原理和架构方式,从中找到新的知识领域,扩展自己的知识边界,丰富自己的专业技能。借助这个游戏,这一篇我们来聊一聊王者荣耀的技术实现以及同步方式,更多的从MOBA(多人在线战术竞争游戏)方向来解析推理王者的实现方案,如若有分析的不尽的方向,欢迎一起探讨改进。以下是主要讲解的几个重点:

  1. 服务器架构
  2. 通信方式
  3. 同步方案
  4. 技能同步
  5. 断线重连

一、服务器架构

不难发现,王者荣耀的服务器采用房间模式,每个玩家登陆以后,然后进入大厅,进行匹配游戏。匹配完成之后,把一起对战的玩家放到一个房间内进行对战。

房间类玩法和MMORPG有很大的不同,在于其在线广播单元的不确定性和广播数量很小,而且需要匹配一台房间服务器让少数人进入一个服务器。

这一类游戏最重要的是其“游戏大厅”的承载量,每个“游戏房间”受逻辑所限,需要维持和广播的玩家数据是有限的,但是“游戏大厅”需要维持相当高的在线用户数,所以一般来说,这种游戏还是需要做“分服”的。而“游戏大厅”里面最有挑战性的任务,就是“自动匹配”玩家进入一个“游戏房间”,这需要对所有在线玩家做搜索和过滤,以及为了更好的体验,会对玩家进行分地区进行匹配,以方便获得更快速的同步。

一般的方式是玩家先登录“大厅服务器”,然后选择组队游戏的功能,服务器会通知参与的所有游戏客户端,新开一条连接到房间服务器上,这样所有参与的用户就能在房间服务器里进行游戏交互了。

二、通信方式

说到通信方式,一般会有http和socket 两种方式,但http底层也是采用socket,只是每次通信完成以后都会断开,这种方式对于需要频繁交互的双方来说,显得效率太低了,所以一般实时要求高的游戏都是采用socket方式来通信。

可是sokect通信,又分为两种:TCP vs UDP,具体是采用那种socket类型,需要具体来看游戏游戏类型。以下是两种类型的优劣:

从上面的对比中,我们可以会发现,关于socket,我们想做的事情,tcp都帮我们做了,我们只需要建立链接,然后像读写文件一样读写就可以了。而udp需要我们自己设计一切。看到这一切,你可能第一感觉就是采用tcp而非udp,那么真实情况是如此么?基于游戏的业务以及场景不同,我可以明确的告诉你,王者荣耀是采用udp的,包括腾讯多数长链接手游都是采用udp,这是为何?

1、tcp保证数据可靠性是有代价的

tcp能够保证数据包的可靠性和有序,这一切都帮你封装好了。TCP发送一个数据包,等待一段时间,直到检测到数据包丢失了,如果没有接收到它的ACK,接下来就重新发送丢失的数据包到目标计算机。重复的数据包将被丢弃在接收端,乱序的数据包将被重新排序。以此来保证数据包的可靠性和有序性。

但为了保证可靠和有序,就要保证TCP无论什么情况,只要数据包出错,就必须等待数据包的重发。这是什么意思呐,就是说,即使最新的数据已经到达,但还是不能访问这些数据包,新到的数据会被放在一个队列中,需要等待丢失的包重新发过来之后,所有数据没有丢失才可以访问。

如此,如果遇到网络环境太差或者不稳定,比如说国内的移动网络,或者是遭遇到了网络阻塞,出现一个数据包丢失,所有事情都需要停下来等待这个数据包重发。客户端会出现等待接收数据,玩家操作会出现卡顿以及响应不及时的现象。

2、udp的可靠性—DIY手动组装

从上面我们可以知道udp主要在可靠性上主要是不能保证数据包的顺序,比如第100个收到的数据包并不一定是第100个发出的数据包,同时也无法保证不丢包,期间有一个包丢失,udp本是也不会去校检。如果这两个问题解决了,udp的大部分可靠性问题也就解决了。

具体的方案我们这一篇就不在细说,大体上是如此来解决:

1、为每个数据包增加序列号,每发一次包,增加本地序号。

2、每个数据包增加一段位域,用来容纳多个确认符。确认字符多少个,跟进应用的发包速率来觉得,速率越高,确认字符的数量也相应越多。

3、每次收到包,把收到的包上序列号变为确认字符,发送包的时候带上这些确认字符。

4、如果从确认字符里面发现某个数据包有丢失,把它留给应用程序来编写一个包含丢失数据的新的数据包,必要的话,这个包还会用一个新的序列号发送。

5、针对多次收到同一包的时候可以放弃它

三、同步方案

游戏中常见的同步方案,有状态同步和帧同步,一般大型的MMOARPG都是采用的是状态同步,比如魔兽世界,状态同步采用C/S架构,所有的状态由服务器来控制,安全性比较高,但是流量比较大。帧同步采用的是囚徒模式,所有c端强制采用一个逻辑帧率,从而保证输出一致,其特点是流量小,安全性比较差。

王者荣耀采用的就是帧同步,那么具体帧同步是什么,如何实现的,我们从两个地方来分解:

1、帧率

什么是帧率,可能没有做过client同学并不是很清楚这个术语,我们从一个小李子来讲解一下。我记得小时候有一种小人书,快速翻看就可以看到漫画上的人物会动起来。如下面这种:

超过1M上传不删了,我也无奈

由于人类眼睛的特殊生理结构,如果所看画面之帧率高于每秒约10-12帧的时候,就会认为是连贯的, 此现象称之为视觉暂留。这也就是为什么电影胶片是一格一格拍摄出来,然后快速播放的,就像上图快速翻小人书一样。

游戏中的所有动画也是采用这种方式来渲染,只不过帧率是有GPU来控制,你所看到的画面都是有都是有GPU一帧帧渲染的,比如30帧/s,你所看到的画面就比较流畅了。而帧率越高你所看到的越流畅。

2、Lockstep—帧同步

帧同步可以说是通过帧率延伸过来的,你可以把一个游戏看成一个巨大的状态机,所有的参与者都采用同一个逻辑帧率来不断的向前推进。

我们看如下2个图:

图中是A、B、C三个玩家的时间轴,这个时间轴不是电脑上的本地时间,而是A、B、C联机时定义的一个时间轴。虚线分隔出来时间片称为turn,可以理解成一帧。箭头表示该玩家将自己的操作指令广播给其他玩家。

我们把一盘游戏看成一个大型的状态机,因为大家玩的是同一款的游戏,因此F是相同的,初始状态S0也是相同的。在第一个turn结束时,所有玩家都接收到了完全一样的输入I,注意这里的I不是一个值,而是包含了当前游戏中所有玩家的操作指令集合。t1时刻所有玩家的电脑自行计算结果。由于F、S0和I是固定的,所以每个玩家电脑上计算出的下一个状态S1一定是相同的。

所以通过上面我们可以知道:

1、我们把游戏的前进分为一帧帧,这里的帧和游戏的渲染帧率并不是一个,只是借鉴了帧的概念,自定义的帧,我们称为turn。游戏的过程就是每一个turn不断向前推进,每一个玩家的turn推进速度一致。

2、每一帧只有当服务器集齐了所有玩家的操作指令,也就是输入确定了之后,才可以进行计算,进入下一个turn,否则就要等待最慢的玩家。之后再广播给所有的玩家。如此才能保证帧一致。

3、Lockstep的游戏是严格按照turn向前推进的,如果有人延迟比较高,其他玩家必须等待该玩家跟上之后再继续计算,不存在某个玩家领先或落后其他玩家若干个turn的情况。使用Lockstep同步机制的游戏中,每个玩家的延迟都等于延迟最高的那个人。

4、由于大家的turn一致,以及输入固定,所以每一步所有客户端的计算结果都一致的。

我们来看看具体的执行流程:

上图中我们可以明显看到,这种囚徒模式的帧同步,在第二帧的时候,因为玩家1有延迟,而导致第二帧的同步时间发生延迟,从而导致所有玩家都在等待,出现卡顿现象。

四、乐观锁&断线重连

囚徒模式的帧同步,有一个致命的缺陷就是,若联网的玩家有一个网速慢了,势必会影响其他玩家的体验,因为服务器要等待所有输入达到之后再同步到所有的c端。另外如果中途有人掉线了,游戏就会无法继续或者掉线玩家无法重连,因为在严格的帧同步的情况下,中途加入游戏是从技术上来讲是非常困难的。因为你重新进来之后,你的初始状态和大家不一致,而且你的状态信息都是丢失状态的,比如,你的等级,随机种子,角色的属性信息等。 比如玩过早期的冰封王座都知道,一旦掉线基本这局就废了,需要重开,至于为何没有卡顿的现象,因为那时都是解决方案都是采用局域网的方式,所以基本是没有延迟问题的。

后期为了解决这个问题,如今包括王者荣耀,服务器会保存玩家当场游戏的游戏指令以及状态信息,在玩家断线重连的时候,能够恢复到断线前的状态。不过这个还是无法解决帧同步的问题,因为严格的帧同步,是要等到所有玩家都输入之后,再去通知广播client更新,如果A服务器一直没有输入同步过来,大家是要等着的,那么如何解决这个问题?

采用“定时不等待”的乐观方式在每次Interval时钟发生时固定将操作广播给所有用户,不依赖具体每个玩家是否有操作更新。如此帧率的时钟在由服务器控制,当客户端有操作的时候及时的发送服务器,然后服务端每秒钟20-50次向所有客户端发送更新消息。如下图:

上图中,我们看到服务器不会再等到搜集完所有用户输入再进行下一帧,而是按照固定频率来同步玩家的输入信息到每一个c端,如果有玩家网络延迟,服务器的帧步进是不会等待的,比如上图中,在第二帧的时候,玩家A的网速慢,那么他这个时候,会被网速快的玩家给秒了(其他游戏也差不多)。但是网速慢的玩家不会卡到快的玩家,只会感觉自己操作延迟而已。

五、技能同步

游戏中有很多是和概率相关的,比如说技能的伤害有一定概率的暴击伤害或者折光被击等。按照帧同步的话,基于相同的输入,每个玩家的client都是独立计算伤害的,那么如何保证所有电脑的暴击伤害一致那。这个时候就需要用到伪随机了。

大部分编程语言内置库里的随机数都是利用线性同余发生器产生的,如果不指定随机种子(Random Seed),默认以当前系统时间戳作为随机种子。一旦指定了随机种子,那么产生的随机数序列就是确定的。就是说两台电脑采用相同的随机种子,第N次随机的结果是一致的。

所以在游戏开始前,服务器为每个玩家分配一个随机种子,然后同步给client,如此每个client在计算每个角色的技能时候,就能保证伤害是一致的。这也是多数帧同步游戏采用的方案,包括王者荣耀。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

小小c#算法题 - 3 - 字符串语句反转

题目:反转语句。 如I love Beijing! 反转后输出 !Beijing love I 特点是指反转单词的顺序,其他字符(这个可以自己指定)不反转。且不能用内置函数,如Split和Substring。 分析:我们需要保证一个单词的字…

unity5.4.3p2里面的AssetBundle打包流程

unity5.4.3p2里面的AssetBundle打包流程,相比之前unity4.x的打包简单了许多,Unity4.X中打包的时候需要自己去管理依赖关系,各种BuildPipeline.PushAssetDependencies()和BuildPipeline.PopAssetDependencies(),一不小心手一抖&…

静态查找表的实现

#ifndef SSTABLE_H #define SSTABLE_H#include <iostream> using namespace std;/************************************************************* SSTable&#xff1a;stastic search table 静态查找表的模板类实现 顺序存储结构 ************************************…

(转)javascript匿名函数

文章来源: http://hi.baidu.com/koen_li/blog/item/4b14e4fc0c9b140c08244d8c.html 匿名函数的写法 顾名思义&#xff0c;就是没有名字的函数&#xff08;⊙﹏⊙b汗&#xff09;。匿名函数通常用于javascript作用域的控制&#xff0c;可以有效的避免对全局变量的污染。常见的匿…

BZOJ3307 雨天的尾巴

题目链接&#xff1a;戳我 树上链修改->差分 每一个节点都开一个权值线段树&#xff0c;最后从下往上合并qwq 代码如下&#xff1a; #include<iostream> #include<cstring> #include<cstdio> #include<algorithm> #include<cmath> #define MA…

主成分分析(PCA)原理详解 2016/12/17 · IT技术 · 主成分分析, 数学 分享到: 21 原文出处: 中科春哥 一、PCA简介 1. 相关背景 主成分分析(Principa

主成分分析&#xff08;PCA&#xff09;原理详解 2016/12/17 IT技术 主成分分析, 数学 分享到&#xff1a;21原文出处&#xff1a; 中科春哥 一、PCA简介 1. 相关背景 主成分分析&#xff08;Principal Component Analysis&#xff0c;PCA&#xff09;&#xff0c; 是一种统…

1 Hadoop简介

1.1 什么是Hadoop 分布式计算平台 优点&#xff1a; 高可靠性 高扩展性 高效性 在各节点之间动态地移动数据&#xff0c;保证各个节点的动态平衡 高容错性 数据多副本&#xff1b;重新启动失败任务 Hadoop应用&#xff1a; Yahoo 广告系统Web搜索研究 Facebook 数据分…

Google Xpath Helper

Google Xpath Helper 下载方法&#xff1a; 1. 访问http://chrome-extension-downloader.com/ 2. 把https://chrome.google.com/webstore/detail/xpath-helper/hgimnogjllphhhkhlmebbmlgjoejdpjl拷贝到文本框里面&#xff0c;然后点击“Download Extention”按钮。 使用方法&am…

【Tensorflow】 Object_detection之训练PASCAL VOC数据集

参考&#xff1a;Running Locally 1、检查数据、config文件是否配置好 可参考之前博客&#xff1a; Tensorflow Object_detection之配置Training Pipeline Tensorflow Object_detection之准备数据生成TFRecord 2、训练模型 PIPELINE_CONFIG_PATH/data/zxx/models/research/date…

2 Hadoop的安装与配置

需要JDK、SSH 对于伪分布式&#xff0c;Hadoop会采取与集群相同的处理方式&#xff1a;按次序启动文件conf/slaves中记载的主机上的进程&#xff0c;只不过在伪分布式中Slave为localhost&#xff08;自身&#xff09;。 Hadoop从三个角度将主机划分为两种角色&#xff1a; 最…

局域网访问控制

访问局域网内其他机器可用如下方式&#xff1a; \\PC-name\d$\dir 或者 \\192.168.xxx.xxx\d$\dir d代表d盘 但前提是对方机器已经把本机用户设置为管理员账户转载于:https://www.cnblogs.com/jimmy-c/p/4116804.html

Unity3d 插值同步

文中大体的思路&#xff1a; A玩家 移动时&#xff0c;本机自行移动&#xff0c;并发送移动指令给服务端&#xff0c;假设移动是成功的&#xff0c;服务端同步其他客户端 B玩家&#xff0c;B玩家 中用一个队列 Queue 来装服务端来的移动指令&#xff0c;然后客户端在updata中做…

laravel数据库相关操作说明

输出原生sql: DB::table(users)->where([[name,,张三]])->toSql(); //输出sql为&#xff1a;select * from users where name?; DB::table(users)->where([[name,,张三]])->getQuery(); //输出sql为&#xff1a;select * from users where name张三; 运行原生sql查…

1 数据挖掘基础

1.1 什么是数据挖掘 从大量数据中挖掘出隐含的、未知的、对决策有潜在价值的关系、模式和趋势&#xff0c;并用这些知识和规则建立用于决策支持的模型&#xff0c;提供预测性决策支持的方法、工具和过程&#xff0c;这就是数据挖掘。 是统计学、数据库技术、人工智能技术的结…

R文件报错的原因

一般R文件报错&#xff0c;无非是资源文件错误&#xff0c;图片命名错误&#xff0c;但是编译都会报错&#xff0c;可以很快解决。但是前几天&#xff0c;引入一个第三方aar包后&#xff0c;项目编译正确&#xff0c;但是就是R文件报错&#xff0c;找不到R文件&#xff0c;整个…

1.0 算法本机调试方法

算法的本机调试方法&#xff1a; 从本地文件中读取测试数据&#xff0c;进行算法调试。 例&#xff1a;读取两个数&#xff0c;输出和。 1 2 11 22 111 222 输出&#xff1a; 3 33 333 #include <fstream> //读取本地文件需要此头文件。调试完成后&#xff0c;提…

[转]Excel数据转化为sql脚本

在实际项目开发中&#xff0c;有时会遇到客户让我们把大量Excel数据导入数据库的情况。这时我们就可以通过将Excel数据转化为sql脚本来批量导入数据库。 1 在数据前插入一列单元格&#xff0c;用来拼写sql语句。 具体写法&#xff1a;"insert into t_student (id,name,age…

void Update ( ) 更新 void FixedUpdate ( )

void Update ( ) 更新 void FixedUpdate ( ) 固定更新 相同点&#xff1a;当MonoBehaviour启用时&#xff0c;其在每一帧被调用&#xff0c;都是用来更新的。 异同点&#xff1a;第一点不同&#xff1a; Update()每一帧的时间不固定&#xff0c;即第一帧与第二帧的时间间隔t…

海量数据库的查询优化及分页算法方案(一)

随着“金盾工程”建设的逐步深入和公安信息化的高速发展&#xff0c;公安计算机应用系统被广泛应用在各警种、各部门。与此同时&#xff0c;应用系统体系的核心、系统数据的存放地――数据库也随着实际应用而急剧膨胀&#xff0c;一些大规模的系统&#xff0c;如人口系统的数据…

【点分治】luoguP2664 树上游戏

应该是一道中等难度的点分&#xff1f;麻烦在一些细节。 题目描述 lrb有一棵树&#xff0c;树的每个节点有个颜色。给一个长度为n的颜色序列&#xff0c;定义s(i,j) 为i 到j 的颜色数量。以及 现在他想让你求出所有的sum[i] 输入输出格式 输入格式&#xff1a; 第一行为一个整数…