zoukankan      html  css  js  c++  java
  • 【HLSDK系列】Delta 详解

    服务端和客户端总是需要互相交换数据,来做到实时的游戏体验。

    很久之前,我们的网速都不是很快,甚至带宽只有 1Mbps (128KB/s)这样的速度,作为当时一个网络实时对战游戏,每时每刻都要传递数据,为了完成各种各样复杂的效果,要传递的数据量自然也就多了。

    为了减少需要发送的数据大小,引擎的程序员开发出了 Delta 模块。

    它能把需要传递的数据的大小压缩到极致,大大减少了网络传输的数据量,使得当时网速很慢的电脑也能流畅地玩游戏!

    如果你看过我的前两篇文章,你一定对 clientdata_t、entity_state_t 有些了解(如果你还没看过,我建议你去看看),查看结构体你会发现里面的成员大多数是 int、float (4字节变量)为了节约网络带宽占用,引擎还会对这些变量进一步处理,才能发给客户端。

    这里就是 Delta 模块发挥的时候了,打开 valve/delta.lst 或者 cstrike/delta.lst 这个文件,能看到这样的代码:

    clientdata_t none                    
    {
        DEFINE_DELTA( flTimeStepSound, DT_INTEGER, 10, 1.0 ),
        
        // ...
        DEFINE_DELTA( m_flNextAttack, DT_FLOAT | DT_SIGNED, 22, 1000.0 ),
    
        // ...
        
        DEFINE_DELTA( m_iId, DT_INTEGER, 5, 1.0 ),
        
        // ...
    }

    首先你看到了眼熟的 clientdata_t 这个结构体名字,接着还有它的成员们。

    我们可以看到 DEFINE_DELTA ( .. ) 里有一些参数,我们逐个来分析它们。

    为了方便讲解,我们从 DEFINE_DELTA( m_iId, DT_INTEGER, 5, 1.0 ) 这行开始。

    第一个参数 m_iId 毫无疑问表示 clientdata_t 里的 m_iId 这个成员变量。

    第二个参数 DT_INTEGER 表示这个成员变量是 整数型。

    第三个参数 5 表示这个变量最多占用多少个“位”(如果你不知道“位”是什么,我建议你搜索“位和字节”来复习一下基础)下文简称占位参数。

    第四个参数 1.0 对于整数型成员变量来说,它总是 1.0 不需要改变

    重点来啦!注意第三个参数,这里是 Delta 模块压缩数据的精髓!我们知道一个 int 型变量要占用 4字节 也就是 32位,它能存下一个超级大的数值,

    但我们的变量可能不需要存这么大的数值,比如我的 m_iId 的值最大就 31,连 1字节 都不够,只需要 5位!

    Delta模块会在发送数据前,根据这个配置文件来精简变量数据(压缩),把要发送的数据压缩到最小!

    比如上面的 m_iId 这个变量,经过 Delta压缩,只剩下 5位,这远远小于一个 int(32位)!Delta 根据配置文件来压缩每个成员变量的大小,到最后,引擎要发送的数据将会变得非常小!

    这里还要解释一下传递小数(FLOAT)时是如何计算位数的,上面提到了一个 1.0 的参数,实际上它是一个倍数,Delta模块在处理小数时,会把小数乘上这个倍数,得到一个整数,

    比如我的 m_flNextAttack 里的数值是 12.55 乘 1000.0 变成 12550 这样一个整数,而这个整数至少需要 13位 才能存得下,所以占位参数至少要写 13 才能发送 12.55 这个小数给客户端。然后客户端再除以 1000.0 就得到了这个小数。

    你一定注意到还有个 DT_SIGNED ,它表示这个变量允许保存负数,它会额外占用 1位 数据,所以写占位参数时,要考虑到它。

    你可以在 delta.lst 里为每个成员变量配置大小,这是非常必要的。当你决定要传递一个新的数据时,请一定要记得配置 delta.lst 不然你的客户端可能会接收到一个错误的数值。

    Delta模块还有十分强大的差异管理功能,服务端不会每一帧都发送完全相同的数据给客户端,这很没必要。Delta会过滤掉没有改变的数据,只发送有变化的部分数据给客户端,进一步减少了数据发送量!

    相信你一定已经被Delta的强大吸引,但是经过Delta压缩的数据,还会经过更高级的数据压缩算法压缩才发送给客户端。。。

    我总觉得我忘了什么事情,等我想起来再补充吧!

  • 相关阅读:
    2022年第一天
    RestTemplate、 Ribbon、 OpenFeign 关系以及OpenFeign使用连接池
    linux下面编写简单的c++程序
    Rocket简介以及单机版安装
    事务源码(二)
    javaagent技术&Attach技术
    gateway网关原理
    Maven自定义插件以及使用
    AotucCrawler 快速爬取图片
    Monkey工具之fastbotiOS实践
  • 原文地址:https://www.cnblogs.com/crsky/p/6881084.html
Copyright © 2011-2022 走看看