using System;
using System.Threading;
using System.Threading.Tasks;
using Vinno.IUS.Common.Log;
using Vinno.vCloud.Common.FIS.Helper;
using Vinno.vCloud.FIS.CrossPlatform.Common.Enum;
using WingInterfaceLibrary.Interface;
using WingInterfaceLibrary.LiveConsultation;
using WingInterfaceLibrary.Request.Education;
namespace Vinno.vCloud.Common.FIS.LiveVideos
{
internal class PushHeartRateKeeperV2
{
private const int _retryLimit = 3;
private int _retryCount = 0;
private readonly string _token;
private readonly ManualResetEvent _waitEvent = new ManualResetEvent(false);
private readonly object _lock = new object();
private readonly ILiveConsultationService _liveConsultationService;
private readonly IEducationService _educationService;
private readonly EnumHeartRateType _heartRateType;
private readonly int _checkInterval;
private string _heartRateCode;
private volatile bool _stopped;
///
/// The envent connection off line when a wrong eche result happened
///
public event EventHandler Offlined;
public PushHeartRateKeeperV2(string token, string consultationCode, int checkInterval, ILiveConsultationService liveConsultationService)
{
_heartRateType = EnumHeartRateType.LiveConsultation;
_token = token;
_heartRateCode = consultationCode;
if (checkInterval <= 0)
{
checkInterval = 5;
}
_checkInterval = checkInterval;
_liveConsultationService = liveConsultationService;
}
public PushHeartRateKeeperV2(string token, string consultationCode, int checkInterval, IEducationService educationService)
{
_heartRateType = EnumHeartRateType.Education;
_token = token;
_heartRateCode = consultationCode;
_checkInterval = checkInterval;
_educationService = educationService;
}
///
/// Start the Heartrate to keep the session available.
///
public void Start()
{
_stopped = false;
Logger.WriteLineInfo($"PushHeartRateKeeperV2 is started,Consultation Code :{_heartRateCode},Token:{_token},Interval:{_checkInterval}");
Task.Run(() =>
{
DoCheck();
});
}
public void SetHeartRateCode(string heartRateCode)
{
lock (_lock)
{
_heartRateCode = heartRateCode;
}
Logger.WriteLineInfo($"PushHeartRateKeeperV2 SetHeartRateCode:{heartRateCode},Token:{_token}");
}
///
/// Stop the Heartrate
///
public void Stop()
{
_stopped = true;
_waitEvent.Set();
Logger.WriteLineInfo($"PushHeartRateKeeperV2 is stopped,Consultation Code :{_heartRateCode},Token:{_token}");
}
private void ExecuteDoCheck()
{
if (_stopped)
{
return;
}
try
{
switch (_heartRateType)
{
case EnumHeartRateType.LiveConsultation:
var liveConsultationHeartRateRequest = new LiveConsultationHeartRateRequest
{
Token = _token,
};
lock (_lock)
{
liveConsultationHeartRateRequest.ConsultationCode = _heartRateCode;
}
var result = JsonRpcHelper.HeartRate(_liveConsultationService, liveConsultationHeartRateRequest);
Logger.WriteLineInfo($"PushHeartRateKeeperV2 HeartRateAsync Send,Token:{_token},HeartRateType:{_heartRateType},ConsultationCode:{_heartRateCode} ");
if (!result.IsSuccess)
{
Logger.WriteLineError($"PushHeartRateKeeperV2 HeartRateAsync Error,Token:{_token},HeartRateType:{_heartRateType},ConsultationCode:{_heartRateCode} ,ErrorCode:{result.ErrorCode}");
if (result.ErrorCode == 833)//ConsultationEnded
{
_stopped = true;
OnOfflined();
}
else
{
if (_retryCount < _retryLimit)
{
_retryCount++;
}
else
{
_stopped = true;
OnOfflined();
}
}
}
else
{
_retryCount = 0;
}
break;
case EnumHeartRateType.Education:
var liveHeartRateRequest = new LiveHeartRateRequest
{
Token = _token,
};
lock (_lock)
{
liveHeartRateRequest.LiveCode = _heartRateCode;
}
var liveConsultationHeartRateResult = JsonRpcHelper.HeartRate(_educationService, liveHeartRateRequest);
Logger.WriteLineInfo($"PushHeartRateKeeperV2 HeartRateAsync Send,Token:{_token},HeartRateType:{_heartRateType},LiveCode:{_heartRateCode} ");
if (!liveConsultationHeartRateResult.IsSuccess)
{
Logger.WriteLineError($"PushHeartRateKeeperV2 HeartRateAsync Error,Token:{_token},HeartRateType:{_heartRateType},LiveCode:{_heartRateCode},ErrorCode is {liveConsultationHeartRateResult.ErrorCode}");
if (_retryCount < _retryLimit)
{
_retryCount++;
}
else
{
_stopped = true;
OnOfflined();
}
}
else
{
_retryCount = 0;
}
break;
}
}
catch (Exception ex)
{
Logger.WriteLineError($"PushHeartRateKeeperV2 error: {ex}");
if (_retryCount < _retryLimit)
{
_retryCount++;
}
else
{
_stopped = true;
OnOfflined();
}
}
if (!_stopped)
{
_waitEvent.WaitOne(TimeSpan.FromSeconds(_retryCount > 0 ? (double)_checkInterval / 2 : _checkInterval));//如果上一次失败,则等待一半时间再试一次
if (!_stopped)
{
DoCheck();
}
}
}
///
/// Do HartRate
///
///
private void DoCheck()
{
Task.Run(new Action(ExecuteDoCheck));
}
private void OnOfflined()
{
Offlined?.Invoke(this, EventArgs.Empty);
}
}
}