#pragma once class HeartbeatChecker { public: enum eSTATUS { CLEAR_FIELD = 0, ENABLED = 1, ARMORKIT_ENABLED = 2, MASK_STATUS = (CLEAR_FIELD|ENABLED|ARMORKIT_ENABLED), }; enum eWARNING_FIELD { RESERVED_FIELD = 0, // ACCEPTABLE_VIOLATION = 1, // Client ÄÄÅÍ ¼º´ÉÀÌ Ã³¸® ·ÎÁ÷»ó ¹ß»ýÇÒ ¼ö ÀÖ´Â ¿ÀÂ÷ º¸Á¤°ª OVERFLOW_SAMEROUND = 2, // µ¿ÀÏ ¶ó¿îµå¿¡ º¹¼ö°³ÀÇ Heartbeat°¡ ¹ß»ýÇÑ È¸¼ö ARMORKIT_SIGNALED = 3, // ArmorKitÀ¸·ÎºÎÅÍ '³ª »ì¾ÆÀÖ¾î'ÇÏ´Â ½ÅÈ£¸¦ ¹ÞÀº ȸ¼ö 1ÀÌ»ó¸¸ µÇ¸é µÈ´Ù. }; public: HeartbeatChecker(); ~HeartbeatChecker(); VOID Init(); // TRUEÀÏ °æ¿ì ÃøÁ¤ ½Ã°£ º¸Á¤ ¹× ÄÁÆ®·Ñ VOID SetEnable( BOOL bSet ); BOOL IsEnabled() { return (BOOL)m_dwStatus&ENABLED; } VOID Signal( User* pUser, DWORD dwCurTick ); DWORD& LifeTimeOut() { return m_dwLifeTimeout; } DWORD& SignaledCount() { return m_dwSignaledCount; } protected: VOID Start(); VOID Stop(); private: DWORD GetNextRound( DWORD dwCurTick, DWORD dwTimeout ); // ¹ÞÀº HeartbeatÁֱⰡ µ¿ÀÏ Áֱ⠳»¿¡ º¹¼ö°³°¡ µé¾î¿Â °æ¿ì ÀÌ¿¡ ´ëÇÑ ´Ü¼ø Æò°¡ ·ÎÁ÷ BOOL CheckOverflow(); // Æò°¡ ÁÖ±â (30round)°¡ µÇ¾úÀ» ¶§, ±× ±â°£µ¿¾È µé¾î¿Â Heartbeat ½ÅÈ£µîµîÀ» ¾î¶»°Ô ó¸®ÇÒ °ÍÀΰ¡? // ¼ö½ÅµÈ Heartbeat°¡ ºñÁ¤»óÀ̰í, À̰ÍÀÌ Çã¿ëÇÒ ¼ö ÀÖ´Â ¼öÄ¡¸¦ ¹þ¾î³¯ °æ¿ì Disconnect¿Í °°Àº 󸮸¦ // ¼öÇàÇÑ´Ù. // ´Ü, À̰ÍÀº Client°¡ Heartbeat¸¦ º¸³»Áö ¾ÊÀ» °æ¿ì¿¡´Â 󸮵ÇÁö ¾ÊÀ¸¹Ç·Î, ¿ÜºÎÀûÀ¸·Î º°µµÀÇ Æò°¡ // Áֱ⸦ °®´Â µ¶¸³µÈ ·ÎÁ÷ÀÌ ¿ä±¸µÈ´Ù. PROCESS_HEARTBEAT_VALUATION°¡ ÀÌ ¿ªÇÒÀ» ¼öÇàÇÏ°Ô µÉ °ÍÀÌ´Ù. BOOL CheckValuationTime( User* pUser ); private: DWORD m_dwStatus; DWORD m_dwLifeTimeout; DWORD m_dwSignaledCount; DWORD m_dwRound; DWORD m_dwTimeout; DWORD m_dwRoundCount; DWORD m_dwAccumulatedCount; BYTE m_pWarningFields[sizeof(DWORD)]; BOOL m_bFirstStart; //DWORD m_dwPauseTime; };