• 网络游戏中的(低精度)时间同步


    对于网络游戏来说。从物体的移动、攻击到最基础的计时等等,都须要client与server保持时间的相对一致,那么server与client同步便是一个必须要解决的问题。通常,网络游戏都会利用心跳来进行同步。那么当client并不须要如此精度的同步时,有没有其它方法呢?这里主要讨论低精度的时间同步(精确到秒)。

    工作中接触过3种简单的时间同步方法:

    首先,定义时间同步类

    /// 32位操作系统
    typedef unsigned int64_t QWORD;
    typedef unsigned long    DWORD;
    
    
    class TimeSynchronize()
    {
    public:
        void ServerTimeSync(QWORD ServerTime);
        QWORD GetLocalTime();
    
    private:
        QWORD initServerTime;
        QWORD initClientTime;
        DWORD initClientTimeFromStartup;
    };
    
    /// 服务器下发同步消息
    void TimeSynchronize::ServerTimeSync(unsigned int64_t serverTime)
    {
        initClientTime = time(NULL);
        initServerTime = serverTime;
        initClientTimeFromStartup = timeGetTime();
    }

    1.当client启动的时候。server向client下发server当前的时间。当client须要获取当前时间时。仅仅需用校正过的时间加上本地时间就可以。

    DWORD TimeSynchronize::GetLocalTime()
    {
        return initServerTime  - initClientTime + time(NULL);   ///< initServerTime  - initClientTime为了消除client与server的时间误差
    }
    看到这里,细心的同学要笑了,这样的做法改动本地的系统时间,不就改动了该函数的返回值么。确实,接口中仅仅要取用了本地时间。便将改动本地时间的风险带入了接口。

    2.server定时向client发送同步消息,就是所谓的心跳机制。类似TCP中的心跳,server定时发送一个自己定义的结构体(心跳包或心跳帧),让对方知道自己“在线”。

    以确保链接的有效性。当server超过一定时间没有收到来自client的回复。则当做玩家掉线,server关闭socket链接。不同的游戏也会依据游戏类型的不同,依据自己的须要设计心跳机制,间隔从几十ms到几s不等。

    那么当client在大部分时间中并不须要高精度的时间同步时,有没有其它办法以减少对server性能的消耗?

    3.利用timeGetTime接口。与同步时获取的server时间模拟当前时间。

    //  timeGetTime:函数以毫秒计的系统时间。该时间为从系统开启算起所经过的时间。 
    //  DWORD timeGetTime(VOID); 
    //  參数:无參数。

    //  返回值:以毫秒值返回系统时间。 DWORD TimeSynchronize::GetLocalTime() { return initServerTime + timeGetTime() - initClientTimeFromStartup + initServerTime - initClientTime; }

    能够看到timeGetTime的返回值精度为(ms),对于精度要求为(s)级的应用来说,已然够用了。

    当然利用timeGetTime()要注意返回值为32位,取值范围为0~2^32,约为49.71天,要避免溢出。

    假设服务端利用该接口,又不便于重新启动server,建议利用精度更高的接口,如:QueryPerformanceFrequency(),QueryPerformanceCounter()。


  • 相关阅读:
    Oracle 获取表结构信息
    EasyUI layout动态设置Split属性
    jquery easyui-datagrid 如何清空数据
    ORacle 复制表
    aspx调用webmethod
    RDLC添加链接
    Nginx 负载均衡 ip_hash , hash key(consistent) url_hash, least_conn
    Nginx 提升吞吐量利器 Keeplived
    Nginx Gzip 的正确使用
    Nginx 切割日志
  • 原文地址:https://www.cnblogs.com/wzjhoutai/p/7105324.html
Copyright © 2020-2023  润新知