123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126 |
- using XGame.Framework.Time;
- using System;
- using XGame.Framework.Interfaces;
- namespace XGame.Framework.Network
- {
- internal class Heartbeat : IHeartbeat, IDisposable
- {
- private IHeartbeatListener _listener;
- private ISessionContext _context;
- public bool Started => _started;
- private bool _started = false;
- private bool _isTimeout = false;
- public int Timeout { get; set; } = 12000;
- public int Interval { get; set; } = 6000;
- private ITimer _timeoutTimer;
- private ITimer _intervalTimer;
- public Heartbeat(IHeartbeatListener listener, ISessionContext context)
- {
- _listener = listener;
- _context = context;
- }
- public void Start()
- {
- if (_started) return;
- Log.Debug("Heartbeat Start.");
- _started = true;
- _intervalTimer = _context.Time.AddLooperTimer(Interval, Send);
- Send(0);
- }
- public void Stop()
- {
- if (!_started) return;
- Log.Debug("Heartbeat Stop.");
- _started = false;
- _isTimeout = false;
- _timeoutTimer?.Cancel();
- _timeoutTimer = null;
- _intervalTimer?.Cancel();
- _intervalTimer = null;
- }
- public void Receive()
- {
- if (!_started) return;
- _timeoutTimer?.Cancel();
- _timeoutTimer = null;
- _isTimeout = false;
- // 重置心跳的定时器,减少心跳次数,若服务器需要固定心跳间隔,则取消该步骤
- (_intervalTimer as IReset)?.Reset();
- }
- private void Send(int times)
- {
- _timeoutTimer?.Cancel();
- _timeoutTimer = _context.Time.AddDelayTimer(Timeout, OnTimeout);
- //心跳Type默认就是0
- var bytes = SessionBufferPool.Acquire();//会在Remote那里回收
- bytes[0] = NetDefine.MAGIC;
- bytes[1] = 0;
- _context.Session.Send(bytes, 0, 2);
- }
- private void OnTimeout()
- {
- if (!_started)
- return;
- if (_isTimeout)
- {
- Log.Warn("Heartbeat 心跳第二次超时");
- Stop();
- _listener?.OnTimeout();
- }
- else
- {
- Log.Warn("Heartbeat 心跳第一次超时");
- _isTimeout = true;
- Send(0); //再次尝试发送
- }
- }
- //private void AddObservable()
- //{
- // _sessionNode.AddListener(EventDefine.SESSION_RECV_ERROR, OnError);
- // _sessionNode.AddListener(EventDefine.SESSION_SEND_ERROR, OnError);
- // _sessionNode.AddListener(EventDefine.SESSION_REMOTE_CLOSED, OnError);
- // _sessionNode.AddListener(EventDefine.SESSION_PUSH_RECVED, OnError);
- // _sessionNode.AddListener(EventDefine.SESSION_RESPONSE_RECVED, OnError);
- //}
- //private void RemoveObservable()
- //{
- // _sessionNode.RemoveListener(EventDefine.SESSION_RECV_ERROR, OnError);
- // _sessionNode.RemoveListener(EventDefine.SESSION_SEND_ERROR, OnError);
- // _sessionNode.RemoveListener(EventDefine.SESSION_REMOTE_CLOSED, OnError);
- // _sessionNode.RemoveListener(EventDefine.SESSION_PUSH_RECVED, OnError);
- // _sessionNode.RemoveListener(EventDefine.SESSION_RESPONSE_RECVED, OnError);
- //}
- //private void OnError(int eventId, object args)
- //{
- // switch (eventId)
- // {
- // case EventDefine.SESSION_RECV_ERROR:
- // case EventDefine.SESSION_SEND_ERROR:
- // case EventDefine.SESSION_REMOTE_CLOSED:
- // Stop();
- // break;
- // case EventDefine.SESSION_PUSH_RECVED:
- // case EventDefine.SESSION_RESPONSE_RECVED:
- // timeoutTimer?.Cancel();
- // break;
- // }
- //}
- void IDisposable.Dispose()
- {
- Stop();
- _listener = null;
- _context = null;
- }
- }
- }
|