Heartbeat.cs 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. using XGame.Framework.Time;
  2. using System;
  3. using XGame.Framework.Interfaces;
  4. namespace XGame.Framework.Network
  5. {
  6. internal class Heartbeat : IHeartbeat, IDisposable
  7. {
  8. private IHeartbeatListener _listener;
  9. private ISessionContext _context;
  10. public bool Started => _started;
  11. private bool _started = false;
  12. private bool _isTimeout = false;
  13. public int Timeout { get; set; } = 12000;
  14. public int Interval { get; set; } = 6000;
  15. private ITimer _timeoutTimer;
  16. private ITimer _intervalTimer;
  17. public Heartbeat(IHeartbeatListener listener, ISessionContext context)
  18. {
  19. _listener = listener;
  20. _context = context;
  21. }
  22. public void Start()
  23. {
  24. if (_started) return;
  25. Log.Debug("Heartbeat Start.");
  26. _started = true;
  27. _intervalTimer = _context.Time.AddLooperTimer(Interval, Send);
  28. Send(0);
  29. }
  30. public void Stop()
  31. {
  32. if (!_started) return;
  33. Log.Debug("Heartbeat Stop.");
  34. _started = false;
  35. _isTimeout = false;
  36. _timeoutTimer?.Cancel();
  37. _timeoutTimer = null;
  38. _intervalTimer?.Cancel();
  39. _intervalTimer = null;
  40. }
  41. public void Receive()
  42. {
  43. if (!_started) return;
  44. _timeoutTimer?.Cancel();
  45. _timeoutTimer = null;
  46. _isTimeout = false;
  47. // 重置心跳的定时器,减少心跳次数,若服务器需要固定心跳间隔,则取消该步骤
  48. (_intervalTimer as IReset)?.Reset();
  49. }
  50. private void Send(int times)
  51. {
  52. _timeoutTimer?.Cancel();
  53. _timeoutTimer = _context.Time.AddDelayTimer(Timeout, OnTimeout);
  54. //心跳Type默认就是0
  55. var bytes = SessionBufferPool.Acquire();//会在Remote那里回收
  56. bytes[0] = NetDefine.MAGIC;
  57. bytes[1] = 0;
  58. _context.Session.Send(bytes, 0, 2);
  59. }
  60. private void OnTimeout()
  61. {
  62. if (!_started)
  63. return;
  64. if (_isTimeout)
  65. {
  66. Log.Warn("Heartbeat 心跳第二次超时");
  67. Stop();
  68. _listener?.OnTimeout();
  69. }
  70. else
  71. {
  72. Log.Warn("Heartbeat 心跳第一次超时");
  73. _isTimeout = true;
  74. Send(0); //再次尝试发送
  75. }
  76. }
  77. //private void AddObservable()
  78. //{
  79. // _sessionNode.AddListener(EventDefine.SESSION_RECV_ERROR, OnError);
  80. // _sessionNode.AddListener(EventDefine.SESSION_SEND_ERROR, OnError);
  81. // _sessionNode.AddListener(EventDefine.SESSION_REMOTE_CLOSED, OnError);
  82. // _sessionNode.AddListener(EventDefine.SESSION_PUSH_RECVED, OnError);
  83. // _sessionNode.AddListener(EventDefine.SESSION_RESPONSE_RECVED, OnError);
  84. //}
  85. //private void RemoveObservable()
  86. //{
  87. // _sessionNode.RemoveListener(EventDefine.SESSION_RECV_ERROR, OnError);
  88. // _sessionNode.RemoveListener(EventDefine.SESSION_SEND_ERROR, OnError);
  89. // _sessionNode.RemoveListener(EventDefine.SESSION_REMOTE_CLOSED, OnError);
  90. // _sessionNode.RemoveListener(EventDefine.SESSION_PUSH_RECVED, OnError);
  91. // _sessionNode.RemoveListener(EventDefine.SESSION_RESPONSE_RECVED, OnError);
  92. //}
  93. //private void OnError(int eventId, object args)
  94. //{
  95. // switch (eventId)
  96. // {
  97. // case EventDefine.SESSION_RECV_ERROR:
  98. // case EventDefine.SESSION_SEND_ERROR:
  99. // case EventDefine.SESSION_REMOTE_CLOSED:
  100. // Stop();
  101. // break;
  102. // case EventDefine.SESSION_PUSH_RECVED:
  103. // case EventDefine.SESSION_RESPONSE_RECVED:
  104. // timeoutTimer?.Cancel();
  105. // break;
  106. // }
  107. //}
  108. void IDisposable.Dispose()
  109. {
  110. Stop();
  111. _listener = null;
  112. _context = null;
  113. }
  114. }
  115. }