Flutter 跨平台开发之路五 多人在线,帧同步,状态同步

一.应用同步发展进程

1.单人应用流程:

玩家按向前走->通过硬件发送传给应用程序->应用程序让玩家面向前->通过速度和时间计算出移动的新位置->设置玩家的人物到新位置

2.多人单机应用流程:

玩家1按向前走(可能玩家2也同时按向前走)->通过硬件发送传给应用程序->应用程序等待一定的时间并在这个时间收集多名玩家的输入->应用程序根据各个玩家的输入处理逻辑->通过速度和时间计算出各个玩家移动的新位置->设置各个玩家的人物到新位置

3.多人在线应用流程:

前端应用玩家1按向前走(可能前端应用玩家2也同时按向前走)->通过网络发送传给应用程序服务器->应用程序服务器等待一定的时间并在这个时间收集多名玩家的输入->应用程序服务器把所有的输入打成一个数据包分发给每个玩家设备的前端应用->每个玩家设备的应用程序根据数据包得到所有玩家的输入->每个玩家设备的应用程序都各自处理所有玩家的输入相应的逻辑->通过速度和时间计算出各个玩家移动的新位置->设置各个玩家的人物到新位置

二.同步相关的技术参数

1.同步时间:

50ms - 100ms (换成每秒帧数 20FPS - 10FPS,这里的上限和下限是根据人类的感知最短时间与操作最快时间的来定的,不是网络传输速率的上下限)

2.每秒带宽:

每位玩家输入的最大字节数 * 玩家数 * 每秒的帧数 * 房间数 * 大厅数 = 总字节数(换算成M:总字节数/1024 得出总KB数 , 再总KB数/1024,得出总M数,也就是常说的你的带宽有多M)

三.同步相关的网络协议

1.TCP:有保序的可靠的传输,通信前需三次握手连接。

  • 保序(如果有一个包发出去,没有收到对方的确认ACK返回信息,就会阻塞等一会再发一次刚刚的包,通过阻塞来保证数据的有序)。
  • 可靠(发送的包会包含校验位,如果有一个数据包,在传输途中少一个字节或其中一个字节变了,那接收方会要校验位来校验数据,如果正确就回个确认ACK,如果不对就丢掉这个包,通过发送和对方确认来保证数据的可靠)。
  • 优点:有序,可靠,适合网络速度要求不高数据量少的应用
  • 缺点:传输慢,报头较大,整个数据包也较大,不适合快节奏的应用,适用于慢节奏数据流式的应用

2.UDP:不保序不可靠的传输,通信前不需要建立连接

  • 无序(乱序,可能先发的<数据包因为选了一条长的路线>比后面发的数据包<选了一条短的路线>而后到对面)。
  • 不可靠(发送后不用等对方回确认ACK,直接进入下一个数据包的发送流程)。
  • 优点:数据包小,速度快
  • 缺点:乱序,丢包(对方可能收不到包)

四.同步相关的框架

1.帧同步:(以帧id序号作为同步的依据,主要逻辑和压力在客户端,优点:流量小,网络传输速度快,玩家体验好,缺点:容易作弊)

  • 服务器定义一个变量now_frameid 来保存当前处在那一帧
  • 服务器定义一个用户结构,结构里用一个变量frame_id来保存每个用户当前处在那一帧
  • 服务器定义一个数组all_frames来保存所有玩家每帧的操作(即数组单元为某帧所有玩家的操作)
  • 服务器定义一个数组frame_operations来保存每帧收集到的客户端操作
  • 服务器定时触发一次逻辑:
    1>.等待客户端操作(操作是带有客户端同步到的sync_frame_id,如果sync_frame_id比用户结构里的frame_id大,说明是帧id有效,把sync_frame_id记录到用户结构里的frame_id,如果是过时无效操作直接丢掉)
    2>.将收集到的客户端操作数组frame_operations保存到数组all_frames
    3>. 给每一个客户端分发用户结构里的frame_id到now_frameid之间的all_frames记录的操作集
    4>.用户结构里的frame_id为now_frameid
    5>.进入下一帧收集
  • 客户端等待接收服务器来的数据包
  • 客户端接收到的帧id小于sync_frame_id同步帧id,说明同步过了,直接丢掉
  • 客户端根据接收到的服务器数据包,用固定的帧时间来更新逻辑
    1>.更新最新帧的操作效果表现
    2>.迭代跳帧逻辑处理(主要位置,动画等逻辑处理,有多少帧就迭代多少次)
    3>.采集玩家操作,上报给服务器

2.状态同步:(以每个物件的状态作为同步的依据,主要逻辑和压力在服务端,优点:不容易作弊,客户性能好,缺点:流量大,网络传输速度慢,玩家体验不是很好,因为要联调才能推进项目开发效率低)

  • 把客户端的主要逻辑搬到服务器
  • 客户端把操作上报给服务器
  • 服务器检查操作有效性
  • 服务器把操作的玩家状态分发给有关系的玩家客户端(如同一个区域内附近的)
  • 服务器跟据操作的玩家状态更新服务器逻辑
  • 各个客户端跟据操作的玩家状态更新自已客户端的逻辑
  • 客户端把操作上报给服务器

五.同步相关的玩家行走实例

1.帧同步:(核心思想:同样的代码+同样输入+同样的时间 ==> 得出同样的结果)

  • 玩家1按向上走 -> 发送操作向上给服务器 -> 服务器接收到操作后 -> 服务器等待帧时间到->服务器广播所有玩家操作集数组给每个客户端 -> 客户端接到玩家1按向上走操作集数组后 -> 根据操作集帧数组用固定的帧时间迭代计算玩家1的位置 -> 得到的最后位置设置给玩家1
  • 客户端重新进游戏 -> 向服务器请求重进 -> 服务器把第1帧到最新帧的操作集帧数组发给重进客户端->客户端迭代逻辑->客户端等待玩家输入

2.状态同步:(核心思想:有状态改变时先服务器和客户端同步状态,然后服务器、客户端各自演算)

  • 玩家1按向上走 -> 发送操作向上给服务器 -> 服务器接收到操作后 -> 服务器检查操作有效性 -> 服务器向相关的玩家客户端广播玩家1向上走的状态 -> 服务器等待更新时间到 -> 服务器计算玩家1的移动新位置并设置玩家1的位置为新位置 -> 各个客户端计算玩家1的移动新位置并设置玩家1的位置为新位置
  • 客户端重新进游戏 -> 向服务器请求重进 -> 服务器把相关的玩家最新状态发给重进客户端(包括位置信息)->等待玩家输入
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值