Пример #1
0
        internal void UnexpectedTermination(Exception exception)
        {
            TerminateAsync();
            OngoingInitialisation = false;

            var secondsOfActiveConnection = (DateTime.Now - (_currentConnectionStarted ?? DateTime.Now)).TotalSeconds;

            Debug.WriteLine($"Event Listener terminated unexpectedly after {secondsOfActiveConnection} seconds.");

            if (AutoReconnect)
            {
                Debug.WriteLine($"{exception.GetType()} occured.");
                if (_firstReconnectAttempt == null)
                {
                    _firstReconnectAttempt = DateTime.Now;
                }
                if (((DateTime)_firstReconnectAttempt).AddMinutes(1) < DateTime.Now)
                {
                    _abortionRequested     = false;
                    _attempts              = 0;
                    _firstReconnectAttempt = null;

                    Debug.WriteLine("Attempting to reconnect...");
                    AttemptedReconnect?.Invoke(this, new AttemptedReconnectEvent(_attempts));
                    InitializeAsync();
                }
                else //recently attempted to reconnect
                {
                    _attempts++;
                    Debug.WriteLine($"Attempting to reconnect... {_attempts}");
                    AttemptedReconnect?.Invoke(this, new AttemptedReconnectEvent(_attempts));

                    if (_attempts >= 3)
                    {
                        _abortionRequested     = true;
                        _attempts              = 0;
                        _firstReconnectAttempt = null;

                        Debug.WriteLine($"Too many reconnection attempts ({_attempts})");
                        Debug.WriteLine($"Event subscription will be terminated. ({_attempts})");
                        TerminatedUnexpectedly?.Invoke(this, new TerminatedUnexpectedlyEvent(exception));
                        Debug.WriteLine("New initialisation required.");
                    }
                    else
                    {
                        InitializeAsync();
                    }
                }
            }
            else
            {
                Debug.WriteLine($"Event subscription will be terminated. ({_attempts})");
                TerminatedUnexpectedly?.Invoke(this, new TerminatedUnexpectedlyEvent(exception));
                AutoReconnect = false;
                Debug.WriteLine("New initialisation required.");
            }
        }
Пример #2
0
        /// <summary>
        ///     Initializes an asynchronous Rest prompt which is read and interpreted.
        ///     Results can be aquired by listening to the relevant event
        /// </summary>
        public async void InitializeAsync(bool autoreconnect = true)
        {
            _abortionRequested = false;
            AutoReconnect      = autoreconnect;

            if (IsInitialized || OngoingInitialisation)
            {
                return;
            }
            OngoingInitialisation     = true;
            _currentConnectionStarted = null;

            Debug.WriteLine("Initialize Event Listener...");
            await Task.Run(() =>
            {
                // asynchronous stream reader
                using (var httpClient = new HttpClient())
                {
                    httpClient.Timeout = TimeSpan.FromMilliseconds(Timeout.Infinite);
                    var requestUri     = $"{OpenHab.RestClient.Url}/events";
                    try
                    {
                        var stream = httpClient.GetStreamAsync(requestUri).Result;

                        using (var reader = new StreamReader(stream))
                        {
                            IsInitialized = true;
                            AttemptedReconnect?.Invoke(this, new AttemptedReconnectEvent(-1));
                            Debug.WriteLine("Event Listener initialized.");
                            _currentConnectionStarted = DateTime.Now;

                            var dataTemplate = new Regex(@"data:\s({.*})");
                            while (!_abortionRequested)
                            {
                                try
                                {
                                    if (reader.EndOfStream)
                                    {
                                        TerminateAsync();
                                        break;
                                    }
                                }
                                catch (Exception e)
                                {
                                    UnexpectedTermination(e);
                                    break;
                                }

                                if (_abortionRequested)
                                {
                                    break;
                                }

                                var currentLine = reader.ReadLine();
                                if (currentLine == null)
                                {
                                    continue;
                                }

                                var data = dataTemplate.Match(currentLine).Groups[1];
                                if (!data.Success)
                                {
                                    continue;
                                }

                                RaiseEvent(data.Value);
                            }
                        }
                    }
                    catch (AggregateException e)
                    {
                        UnexpectedTermination(e);
                    }
                }

                if (_currentConnectionStarted == null)
                {
                    return;
                }
                var secondsOfActiveConnection = (DateTime.Now - _currentConnectionStarted.Value).TotalSeconds;
                Debug.WriteLine($"Event Listener terminated after {secondsOfActiveConnection} seconds.");
            });
        }