using System; using System.Collections.Generic; using System.Threading.Tasks; using System.Timers; using Newtonsoft.Json; using Plugins.Countly.Enums; using Plugins.Countly.Helpers; using Plugins.Countly.Models; namespace Plugins.Countly.Services.Impls.Actual { public class SessionCountlyService { private Timer _sessionTimer; private DateTime _lastSessionRequestTime; public bool IsSessionInitiated { get; private set; } private DateTime _lastInputTime; private readonly CountlyConfigModel _configModel; private readonly PushCountlyService _pushCountlyService; private readonly RequestCountlyHelper _requestCountlyHelper; private readonly IOptionalParametersCountlyService _optionalParametersCountlyService; private readonly EventNumberInSameSessionHelper _eventNumberInSameSessionHelper; public SessionCountlyService(CountlyConfigModel configModel, PushCountlyService pushCountlyService, RequestCountlyHelper requestCountlyHelper, IOptionalParametersCountlyService optionalParametersCountlyService, EventNumberInSameSessionHelper eventNumberInSameSessionHelper) { _configModel = configModel; _pushCountlyService = pushCountlyService; _requestCountlyHelper = requestCountlyHelper; _optionalParametersCountlyService = optionalParametersCountlyService; _eventNumberInSameSessionHelper = eventNumberInSameSessionHelper; } /// /// Intializes the timer for extending session with specified interval /// /// In milliseconds private void InitSessionTimer() { if (_configModel.EnableManualSessionHandling) return; _sessionTimer = new Timer {Interval = _configModel.SessionDuration * 1000}; _sessionTimer.Elapsed += SessionTimerOnElapsedAsync; _sessionTimer.AutoReset = true; } /// /// Extends the session after the session duration is elapsed /// /// /// private async void SessionTimerOnElapsedAsync(object sender, ElapsedEventArgs elapsedEventArgs) { var sessionOver = (DateTime.Now - _lastInputTime).TotalSeconds >= _configModel.SessionDuration; if (IsSessionInitiated && sessionOver) { _requestCountlyHelper.ProcessQueue(); await ExecuteEndSessionAsync(); } else if(IsSessionInitiated) { if (!_configModel.EnableManualSessionHandling) { await ExtendSessionAsync(); } } } public async void UpdateInputTime() { _lastInputTime = DateTime.Now; if (!IsSessionInitiated && _sessionTimer == null) //session was over { await ExecuteBeginSessionAsync(); } } public async Task ExecuteBeginSessionAsync() { FirstLaunchAppHelper.Process(); _lastSessionRequestTime = DateTime.Now; //Session initiated IsSessionInitiated = true; _eventNumberInSameSessionHelper.RemoveAllEvents(); //if (ConsentModel.CheckConsent(FeaturesEnum.Sessions.ToString())) //{ var requestParams = new Dictionary { {"begin_session", 1}, {"ignore_cooldown", _configModel.IgnoreSessionCooldown} }; requestParams.Add("metrics", JsonConvert.SerializeObject(CountlyMetricModel.Metrics, Formatting.Indented, new JsonSerializerSettings {NullValueHandling = NullValueHandling.Ignore})); requestParams.Add("ip_address", _optionalParametersCountlyService.IPAddress); var response = await _requestCountlyHelper.GetResponseAsync(requestParams); //Extend session only after session has begun // if (response.IsSuccess) // { //Start session timer if (!_configModel.EnableManualSessionHandling) { InitSessionTimer(); _sessionTimer.Start(); } // } //} return response; } public async Task ExecuteEndSessionAsync(bool disposeTimer = true) { //if (ConsentModel.CheckConsent(FeaturesEnum.Sessions.ToString())) //{ IsSessionInitiated = false; _eventNumberInSameSessionHelper.RemoveAllEvents(); var requestParams = new Dictionary { {"end_session", 1}, {"session_duration", (DateTime.Now - _lastSessionRequestTime).TotalSeconds}, {"ignore_cooldown", _configModel.IgnoreSessionCooldown.ToString().ToLower()} }; requestParams.Add("metrics", JsonConvert.SerializeObject(CountlyMetricModel.Metrics, Formatting.Indented, new JsonSerializerSettings {NullValueHandling = NullValueHandling.Ignore})); var response = await _requestCountlyHelper.GetResponseAsync(requestParams); if (!_configModel.EnableManualSessionHandling) { //Do not extend session after session ends if (disposeTimer) { _sessionTimer.Stop(); _sessionTimer.Dispose(); _sessionTimer.Close(); _sessionTimer = null; } } //} return response; } /// /// Initiates a session by setting begin_session /// public async Task BeginSessionAsync() { var result = await ExecuteBeginSessionAsync(); //Enables push notification on start if (_configModel.NotificationMode != TestMode.None) { _pushCountlyService.EnablePushNotificationAsync(_configModel.NotificationMode); } return result; } /// /// Ends a session by setting end_session /// public async Task EndSessionAsync() { return await ExecuteEndSessionAsync(); } /// /// Extends a session by another 60 seconds /// public async Task ExtendSessionAsync() { _lastSessionRequestTime = DateTime.Now; //if (ConsentModel.CheckConsent(FeaturesEnum.Sessions.ToString())) //{ var requestParams = new Dictionary { { "session_duration", _configModel.SessionDuration }, {"ignore_cooldown", _configModel.IgnoreSessionCooldown.ToString().ToLower()} }; requestParams.Add("metrics", JsonConvert.SerializeObject(CountlyMetricModel.Metrics, Formatting.Indented, new JsonSerializerSettings {NullValueHandling = NullValueHandling.Ignore})); return await _requestCountlyHelper.GetResponseAsync(requestParams); //} } #region Unused Code ///// ///// The method must be used only when Manual Session Handling is disabled. ///// Sets the session duration. Session will be extended each time this interval elapses. The interval value must be in seconds. ///// ///// //private static void SetSessionDuration(int interval) //{ // if (!IsManualSessionHandlingEnabled) // { // _extendSessionInterval = interval; // _sessionTimer.Interval = _extendSessionInterval * 1000; // } //} #endregion } }