1. 程式人生 > >HeartBeatCtrl:手機遊戲中,心跳包的使用

HeartBeatCtrl:手機遊戲中,心跳包的使用

在平時玩手機遊戲的時候,有時候會碰到網路斷開連線的情況,那麼在工程中,我們是怎麼解決這種情況的呢?

沒錯,心跳包,在遊戲過程中,每過一段時間,客戶端會向伺服器傳送一個很短或者空的資料,根據判斷是否有返回的資料,可以知道,是否正在連線。介紹不多說,我們看程式碼

local IDispose=require("Core/IDispose")
local HeartbeatCtrl = class("HeartbeatCtrl",IDispose);

HeartbeatCtrl.MAX_DELAY_TIME=30--檢測心跳的時間
--心跳包控制器
function HeartbeatCtrl:ctor()
    self:EventInit()
    self:SocketInit()
end

function HeartbeatCtrl:SocketInit()
    _G_Socket:AddPropertyEvent(SocketStatic.SERVER_LOGIN,HeartbeatCtrl.Start,self)
    _G_Socket:AddPropertyEvent(rpc_info.rpc_dict.keepAlive,HeartbeatCtrl.HeartbeatCallBack,self)
end

function HeartbeatCtrl:RemoveSocket()
    _G_Socket:RemovePropertyEvent(SocketStatic.SERVER_LOGIN,HeartbeatCtrl.Start,self)
    _G_Socket:RemovePropertyEvent(rpc_info.rpc_dict.keepAlive,HeartbeatCtrl.HeartbeatCallBack,self)
end

function HeartbeatCtrl:EventInit()

    _G_Dispatcher:AddPropertyEvent(GameStatic.START_ENTER_GAME,HeartbeatCtrl.Stop,self);
    _G_Dispatcher:AddPropertyEvent(GameStatic.SERVER_SHUT_DOWN,HeartbeatCtrl.Stop,self);
end

function HeartbeatCtrl:RemoveEvent()

    _G_Dispatcher:RemovePropertyEvent(GameStatic.START_ENTER_GAME,HeartbeatCtrl.Stop,self);
    _G_Dispatcher:RemovePropertyEvent(GameStatic.SERVER_SHUT_DOWN,HeartbeatCtrl.Stop,self);
end

function HeartbeatCtrl:Start()
    -- print("===========================    開啟心跳       ========================")
    self.sendCount=0
    self.receiveCount=0
    self.lastReceiveTime=0
    self.lastSendTime=0
    self.lastDelayTime=0
    self.timer = Timer.New(function()self:Heartbeat() end,25,-1,false)
    self.timer:Start()
    self:Heartbeat()

    FixedUpdateBeat:Add(self.Update, self)
end

function HeartbeatCtrl:Update(deltaTime,unscaledDeltaTime)
    if self:CheckTimeOut()==true then 
        self:Stop()
        self:TimerClean()
        --[[_G_Dispatcher:AddPropertyEvent(GameStatic.RE_CONNECT_SERVER_SUCESS,HeartbeatCtrl.ReConnectServerSucess,self)
        PreloadTip.instance:ShowStayTips("連線中斷,正在嘗試重新連線...");--]]
        Network.ConnectFailed()  
        -- local data = {}
        -- data.text = "斷開連線,是否重新連線遊戲?"
        -- data.callback = function() Game.EnterGame() end
        -- CommonPopup(data)
    end
end

function HeartbeatCtrl:ReConnectServerSucess()
    PreloadTip.instance:Reset()
    _G_CtrlManager.ins.login:SendEnterGame()
    self:Start()
    _G_Dispatcher:RemvoePropertyEvent(GameStatic.RE_CONNECT_SERVER_SUCESS,HeartbeatCtrl.ReConnectServerSucess,self)

end

function HeartbeatCtrl:Stop()
    self:TimerClean()
    FixedUpdateBeat:Remove(self.Update, self)
end

function HeartbeatCtrl:HeartbeatCallBack(eventType,dispatch)
    self.receiveCount=self.receiveCount+1
    self.lastReceiveTime=os.time()
    self.lastDelayTime = self.lastReceiveTime - self.lastSendTime;

    local serverTime=dispatch.now
    _G_TimerManager:SetServerTime(serverTime)
end

--獲取上一次的延時資訊
function HeartbeatCtrl:GetLastDelayTime()
    if self.sendCount == self.receiveCount then
        return self.lastDelayTime;
    end

    local currentDelayTime = os.time() - self.lastSendTime;
    if currentDelayTime < self.lastDelayTime then 
        return self.lastDelayTime;
    end
    
    return currentDelayTime;
end

function HeartbeatCtrl:Heartbeat()
    self.sendCount=self.sendCount+1
    self.lastSendTime=os.time()
    
    local id = rpc_info.rpc_dict.keepAlive
    local data = {}
    Network.SendMessage(id,data)
end

function HeartbeatCtrl:CheckTimeOut()
    -- print(self:GetLastDelayTime(),self.sendCount,self.receiveCount)
    -- if not self.test then 
    --     self.test=true
    --     return true
    -- end
    return self:GetLastDelayTime() > HeartbeatCtrl.MAX_DELAY_TIME
end

function HeartbeatCtrl:TimerClean()
    if self.timer then 
        self.timer:Stop();
        self.timer=nil
    end
end

function HeartbeatCtrl:Dispose()
    self:RemoveSocket()
    self:RemoveEvent()
    self:TimerClean()
end

return HeartbeatCtrl
我們可以看到,在一開始函式初始化的時候,我們添加了Start方法初始化各個計數器的值,然後添加了Update方法開始計時,每隔固定的時間,客戶端會發送訊息給伺服器,根據傳送訊息的時間及接受時的延時時間差,確認連線正常,如果超出規定時間,判斷連線失敗,進行重連方法。如果連線成功,計數器清零,準備進行下一次的心跳包傳送。

相關推薦

HeartBeatCtrl手機遊戲心跳的使用

在平時玩手機遊戲的時候,有時候會碰到網路斷開連線的情況,那麼在工程中,我們是怎麼解決這種情況的呢?沒錯,心跳包,在遊戲過程中,每過一段時間,客戶端會向伺服器傳送一個很短或者空的資料,根據判斷是否有返回的資料,可以知道,是否正在連線。介紹不多說,我們看程式碼local IDis

“驅逐邊界”的手機戰役誰將引領 “全面屏普及潮”

手機戰役 智能手機的發展,從按鍵手機到大屏幕,距今已經持續了10年時間。無論是對於廠商還是消費者而言,都需要一個新的熱點來重新打開智能手機的藍海市場。從2016年開始出現的全面屏手機,不得不說是最具希望能承載各方期待的產物。只是,目前全面屏手機這個概念還處於萌芽期,雖能讓消費者感受到“全面屏”所帶來的視覺體驗

實用技巧Spring Cloud如何優雅下線微服務?

原文:http://www.itmuch.com/spring-cloud-sum/how-to-unregister-service-in-eureka/ ,轉載請說明出處。 在生產環境中,服務的上下線是不可避免的,我們希望能夠優雅地下線微服務。本文基於Spring Boot 2.x + Spring

1.問題一在oracle連續十次嘗試登陸不成功那麼此賬戶將會被鎖定(lock)。當使用被鎖定的賬戶登入時系統會報錯ORA-28000: the account is locked。

解決思路: 以管理員的身份登入,即以sys或者system登入資料庫; 使用命令解鎖使用者:alter user 這裡是使用者名稱 account unlock; 重置密碼:alter user 這裡是使用者名稱 identified by 這裡是重置的密碼; 重新登入即可。

laravel框架手機驗證註冊簡訊提供商

一篇介紹基於laravel框架實現簡訊驗證碼註冊的demo文章。文章篇幅適中,適宜閱讀,有不清楚的地方可以私信博主詢問,謝謝大家:) 1. 服務商註冊 簡訊的服務商有很多,這裡介紹雲片,選擇雲片作為我們的簡訊服務商,註冊成功後,會有 10 條簡訊的免費額度,但願

【本人禿頂程式設計師】實用技巧Spring Cloud如何優雅下線微服務

←←←←←←←←←←←← 我都禿頂了,還不點關注! 在生產環境中,服務的上下線是不可避免的,我們希望能夠優雅地下線微服務。本文基於Spring Boot 2.x + Spring Cloud Finchley講解實際專案中優雅下線服務的四種方式,並探討各方式的優缺點。 注:S

對話在敏捷是否可以仍然用需求來替代使用者故事?

Alan S Koch:When we link Agile to traditional frameworks like CMMI, we tend to talk about User Stories as being equivalent to Requirements. But as Niels p

冷門Dojo Gridx如何編寫一個module

DOJO 是一個開源的 Javascript 開發框架,最近版本是1.9,類似的還有大名鼎鼎的Jquery, YUI 等等。 因為工作的原因最近接觸了這個框架,奇怪的是好像在業界DOJO並不流行,網上資料也較少,只有IBM在大力的推動,看來效果也是差強人意,感覺是個冷門的玩意。經過幾天的接觸覺得這個

Netty(三)網路傳輸的拆、粘問題

問題來源:     在Netty中對於TCP傳輸的預設資料大小為1024位元組,當資料包不超過1024時,會一次接收完畢,當超過1024時,首先會進行拆分,即分成幾次傳輸,等到下次連線時將會改變一次

知乎問題"房間裡100個人每人1000元他們玩一個遊戲每輪遊戲每個人拿出1元隨機給另一個人最後他們的財富分佈是怎樣的"實踐解答

知乎上有個有趣的問題,房間裡100個人,每人1000元,他們玩一個遊戲,每輪遊戲中,每個人拿出1元,隨機給另一個人,最後他們的財富分佈是怎樣的? 朋友圈有轉文章《用資料分析告訴你這個世界》分析,可以負債的情況下,17000次後,接近冪律分佈。 驗證如下,結論就是該文章在資

eclipse技巧在eclipse開啟jar的api

在eclipse中開啟jar包的api 右擊jar檔案 –> 屬性 –> Javadoc Location,如下圖所示: 在eclipse中按F1即可出現help,如下:

關於小米手機開發不能列印、檢視logcat日誌的解決方法。

最近在開發過程中使用小米手機作為測試機的時候發現沒有logcat日誌輸出。在網上找來找去終於找到了一篇解決的有效部落格,這裡特別記錄一下,也希望能幫到別人。 解決辦法如下: 在電腦上找到 .Android資料夾,win下在C:\Users\dell.andr

shape檔案用法二在Android用XML檔案實現圓角的效果

需求:好多時候,需要給元件加入圓角的效果,如下圖所示: 現在,要做的就是,實現 圖中所示的圓角效果。 第一步:在 res/drawable檔案下新增 ,檔案: btn_background_shape.xml 檔案。 /TestShape2/res/drawable/

在FPS遊戲玩家對音畫同步感知的量化與評估

前言 在遊戲測試中,音畫同步測試是個難點(所謂遊戲音畫同步:遊戲中,音效與畫面的同步程度),現在一般採用人工主觀判斷的方式測試,但這會帶來2個問題: 無法準確量化,針對同一場景的多次測試結果可能會相反; 人力投入與業務場景數成正比; 本文主要內容: 一、 音畫同步測試方案 二、 玩家對FPS遊戲音畫不同

Unity3d修煉之路遊戲開發3d數學知識的練習【1】(不斷更新.......)

turn tor rdo pre 長度 scrip 縮放 unity3d float #pragma strict public var m_pA : Vector3 = new Vector3(2.0f, 4.0f, 0.0f); public var m_pB :

電腦頁面放到手機顯示時遇到了一個奇怪的問題字體的顯示大小與在CSS指定的大小不一致

inf 通過 左右 可能 標簽 其他 size idt min-width 最近在做一個手機端頁面時,遇到了一個奇怪的問題:字體的顯示大小,與在CSS中指定的大小不一致。大家可以查看這個Demo(記得打開Chrome DevTools)。 就如上圖所示,你可以發現,原本指定

黑馬基礎階段測試題創建Phone(手機)類Phone類包含以下內容

ring post power 試題 println one 控制臺 sta 創建 package com.swift; public class Phone { private String pinpai; private int dianl

面試題應用很多jar比如spring、mybatis、redis等等各自用的日誌系統各異怎麼用slf4j統一輸出?

一、問題概述 如題所說,後端應用(非spring boot專案)通常用到了很多jar包,比如spring系列、mybatis、hibernate、各類連線資料庫的客戶端的jar包。可能這個jar包用的是logback、那個用的是log4j、那個又是log4j2, 這時候,怎麼才能保證各jar包的日誌都能輸

面試題應用很多jar比如spring、mybatis、redis等等各自用的日誌系統各異怎麽用slf4j統一輸出?

相同 如何 align 等等 version 試題 ava body jakarta 一、問題概述 如題所說,後端應用(非spring boot項目)通常用到了很多jar包,比如spring系列、mybatis、hibernate、各類連接數據庫的客戶端的jar包。可能這

24點遊戲是經典的紙牌益智遊戲。 常見遊戲規則 從撲克每次取出4張牌。使用加減乘除第一個能得出24者為贏。(其中J代表11Q代表12K代表13A代表1)按照要求程式設計解決24點遊戲

24點遊戲是經典的紙牌益智遊戲。 常見遊戲規則: 從撲克中每次取出4張牌。使用加減乘除,第一個能得出24者為贏。(其中,J代表11,Q代表12,K代表13,A代表1),按照要求程式設計解決24點遊戲。 基本要求: 隨機生成4個代表撲克牌牌面的數字字母,程式自動列