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); } } }