使用示例

  1. // ************************************************************
  2. // ************************************************************
  3. auto heartBeat = new HeartBeat; // 新建一个心跳
  4. heartBeat->setTimeGap( 3.0f )
  5. ->setTimeOut( 5.0f );
  6. // 当heart beat计时超过TimeGap,状态切换为Checking,触发onGapTimeOut。
  7. // 如果没有及时reset,计时超过timeOut,则状态切换为Broken,触发onHeartBroken,表示确定没有心跳了
  8. heartBeat->onGapTimeOut = [&]()
  9. {
  10. // 表示socket一直没有收到消息,已经超时
  11. // 一般地,我们应该在这里主动发送一个心跳包
  12. CCLOG( "gap time out, we should send a heart beat" );
  13. };
  14. heartBeat->onHeartBroken = [&]()
  15. {
  16. // 表示接收心跳包超时,这时我们一般会主动关闭连接,并多次尝试重连
  17. // 如果还是重连失败,则意味着无法访问当前网络。
  18. CCLOG( "heart beat broken. there's problem with the network." );
  19. };
  20. // ************************************************************
  21. // ************************************************************
  22. WebSocket* websocket = new WebSocket();
  23. websocket->init(......); // 发起连接
  24. websocket.onOpen = [](){ // 连接成功
  25. heartBeat->start(); // 心跳开始计时
  26. };
  27. websocket.onMessage = [](){ // 收到消息
  28. heartBeat->reset(); // 收到一个消息,表示网络正常,重置心跳的计时时间和状态
  29. };
  30. websocket.onError = [](){ // 消息出错
  31. };
  32. websocket.onClose = [](){ // 消息出错
  33. heartBeat->reset(); // 链接关闭,停止心跳
  34. };

HeartBeat.h

  1. class HeartBeat : public cocos2d::Ref
  2. {
  3. enum Status
  4. {
  5. STOP,
  6. Beating,
  7. Checking,
  8. Broken,
  9. DEFAULT = STOP,
  10. };
  11. public:
  12. HeartBeat();
  13. ~HeartBeat();
  14. HeartBeat* start();
  15. HeartBeat* stop();
  16. HeartBeat* reset();
  17. HeartBeat* setTimeGap( const float &timegap );
  18. HeartBeat* setTimeOut( const float &timeout );
  19. std::function<void()> onGapTimeOut;
  20. std::function<void()> onHeartBroken;
  21. private:
  22. void update( float dt );
  23. private:
  24. float _timeGap;
  25. float _timeOut;
  26. float _lastBeatInterval;
  27. Status _status;
  28. };

HeartBeat.cpp

  1. HeartBeat::HeartBeat() :
  2. _lastBeatInterval( -1 ),
  3. _status( Status::DEFAULT ),
  4. _timeGap( 5.0f ),
  5. _timeOut( 5.0f )
  6. {
  7. cocos2d::Director::getInstance()->getScheduler()->schedule(
  8. CC_SCHEDULE_SELECTOR( HeartBeat::update ), this,
  9. 1.0f, // 每秒执行1次
  10. CC_REPEAT_FOREVER, // 一直重复
  11. 0.0, // 0.0s后开始执行第1次
  12. true ); // 初始状态是pause
  13. }
  14. HeartBeat::~HeartBeat()
  15. {
  16. _lastBeatInterval = 0.0f;
  17. _status = STOP;
  18. cocos2d::Director::getInstance()->getScheduler()->unschedule( CC_SCHEDULE_SELECTOR( HeartBeat::update ), this );
  19. }
  20. HeartBeat* HeartBeat::start()
  21. {
  22. if( _status != Beating )
  23. {
  24. _status = Beating;
  25. _lastBeatInterval = 0.0f;
  26. cocos2d::Director::getInstance()->getScheduler()->resumeTarget( this );
  27. }
  28. return this;
  29. }
  30. HeartBeat* HeartBeat::stop()
  31. {
  32. if( _status != STOP )
  33. {
  34. _status = STOP;
  35. _lastBeatInterval = 0.0f;
  36. cocos2d::Director::getInstance()->getScheduler()->pauseTarget( this );
  37. }
  38. return this;
  39. }
  40. HeartBeat* HeartBeat::reset()
  41. {
  42. switch( _status )
  43. {
  44. case HeartBeat::Beating:
  45. case HeartBeat::Checking:
  46. {
  47. _lastBeatInterval = 0.0f;
  48. _status = Beating;
  49. }
  50. break;
  51. }
  52. return this;
  53. }
  54. HeartBeat* HeartBeat::setTimeGap( const float &timegap )
  55. {
  56. _timeGap = timegap;
  57. return this;
  58. }
  59. HeartBeat* HeartBeat::setTimeOut( const float &timeout )
  60. {
  61. _timeOut = timeout;
  62. return this;
  63. }
  64. void HeartBeat::update( float dt )
  65. {
  66. switch( _status )
  67. {
  68. case Beating:
  69. {
  70. if( _lastBeatInterval + dt > _timeGap )
  71. {
  72. _status = Checking;
  73. _lastBeatInterval = 0.0f;
  74. if( onGapTimeOut )
  75. {
  76. onGapTimeOut();
  77. }
  78. }
  79. else
  80. {
  81. _lastBeatInterval += dt;
  82. }
  83. }
  84. break;
  85. case Checking:
  86. {
  87. if( _lastBeatInterval + dt > _timeOut )
  88. {
  89. _status = Broken;
  90. _lastBeatInterval = 0.0f;
  91. if( onHeartBroken )
  92. {
  93. onHeartBroken();
  94. }
  95. }
  96. else
  97. {
  98. _lastBeatInterval += dt;
  99. }
  100. }
  101. break;
  102. default:
  103. break;
  104. }
  105. }