Ejemplo n.º 1
0
        /// <summary>
        ///     Signals connecting on Start() failed.
        /// </summary>
        /// <param name="failSilently">
        ///     Whether the connection attempt was automatically triggered or user-triggered.
        ///     If not user-triggered, reconnection behaviour should not be broken.
        /// </param>
        protected virtual void OnConnectFailed(bool failSilently, Exception exc = null)
        {
            var sb = new StringBuilder();

            sb.Append("Connection failed");
            if (exc != null)
            {
                sb.Append(": ");
                sb.Append(exc.Message);
                if (exc.InnerException != null)
                {
                    sb.AppendFormat(" [{0}]", exc.InnerException);
                }
            }

            if (ReconnectBehavior == ReconnectBehavior.ReconnectAlways)
            {
                _state = ConnectionState.Connecting;
                ApplyReconnectBehavior();
            }
            else
            {
                _state = ConnectionState.Disconnected;
            }

            _areStartStop.Set();

            ConnectingFailed?.Invoke(this, new ConnectingFailedArgs(sb.ToString(), exc, failSilently));
            _logger.Error(exc, sb.ToString());
        }
Ejemplo n.º 2
0
        private async Task <ReconnectionResult> ReconnectIfRequiredAsync()
        {
            if (_mqttClient.IsConnected)
            {
                return(ReconnectionResult.StillConnected);
            }

            try
            {
                await _mqttClient.ConnectAsync(Options.ClientOptions).ConfigureAwait(false);

                return(ReconnectionResult.Reconnected);
            }
            catch (Exception exception)
            {
                ConnectingFailed?.Invoke(this, new MqttManagedProcessFailedEventArgs(exception));
                return(ReconnectionResult.NotConnected);
            }
        }
 public async Task Handle(ConnectingFailed notification, CancellationToken cancellationToken)
 {
     Console.WriteLine($"Connection to broker {Configuration.Host}:{Configuration.Port} failed, attempting reconnect in {ReconnectAfter.TotalSeconds}s ..");
     await Mediator.Publish(new ReconnectRequest(), cancellationToken);
 }
        public async Task <TLCFIClientSession> GetNewSession(IPEndPoint endPoint, TLCFIClientStateManager stateManager, CancellationToken token)
        {
            if (token.IsCancellationRequested)
            {
                return(null);
            }

            lock (_locker)
            {
                if (_activeSession != null && !_activeSession.Connected)
                {
                    _logger.Warn("A session with {0}:{1} already exists, but is not connected. It will be disposed of.",
                                 _activeSession.RemoteEndPoint.Address, _activeSession.RemoteEndPoint.Port);
                    DisposeActiveSession();
                    return(null);
                }
                if (_activeSession != null)
                {
                    _logger.Warn("There already is a connected session with {0}:{1}. Simultaneous sessions are not allowed.",
                                 _activeSession.RemoteEndPoint.Address, _activeSession.RemoteEndPoint.Port);
                    return(null);
                }
            }

            // Succesful registration interval
            if (DateTime.Now.Subtract(_lastSuccesfulRegister).TotalSeconds < 42)
            {
                var remaining = (int)(42 - DateTime.Now.Subtract(_lastSuccesfulRegister).TotalSeconds) + 1;
                _logger.Info("Need 42 seconds between succesful register calls. Still need to wait {0} seconds. ",
                             remaining);
                await Task.Run(async() =>
                {
                    while (remaining > 0)
                    {
                        await Task.Delay(1000, token);
                        remaining--;
                        if (remaining > 0)
                        {
                            _logger.Trace("Starting new session in {0} seconds.", remaining);
                        }
                    }
                }, token);
            }

            _tokenSource = new CancellationTokenSource();
            var session = new TLCFIClientSession(stateManager, endPoint, _tokenSource.Token);

            _activeSession                      = session;
            session.SessionEnded               += OnSessionEnded;
            session.Disconnected               += OnSessionDisconnected;
            session.ControlStateSetToError     += OnSessionControlStateSetToError;
            session.ReceiveAliveTimeoutOccured += OnSessionReceiveAliveTimeout;
            session.EventOccured               += OnSessionEventOccured;

            var watch = new Stopwatch();

            watch.Reset();

            var sesIp   = endPoint.Address.ToString();
            var sesPort = endPoint.Port.ToString();

            while (!session.Connected)
            {
                try
                {
                    var remaining = _timeout - watch.ElapsedMilliseconds;
                    if (remaining > 0)
                    {
                        await Task.Delay((int)remaining, token);
                    }
                    _tries++;
                    // Backoff procedure
                    if (_tries >= 25)
                    {
                        _timeout = 60000;
                    }
                    else if (_tries >= 21)
                    {
                        _timeout = 30000;
                    }
                    else if (_tries >= 10)
                    {
                        _timeout = 5000;
                    }
                    else if (_tries >= 5)
                    {
                        _timeout = 2000;
                    }
                    watch.Reset();
                    watch.Start();
                    _logger.Info("Connecting to {0}:{1}, try {2}", sesIp, sesPort, _tries);
                    ConnectingStarted?.Invoke(this, _tries);
                    if (token.IsCancellationRequested || _tokenSource.IsCancellationRequested)
                    {
                        return(null);
                    }

                    await session.StartSessionAsync(_timeout);
                }
                catch (TaskCanceledException)
                {
                    return(null);
                }
                catch
                {
                    _logger.Warn("Connecting to {0}:{1} try {2} failed", sesIp, sesPort, _tries);
                    ConnectingFailed?.Invoke(this, _tries);
                }
            }

            _logger.Info("TCP session with {0}:{1} started", sesIp, sesPort);
            TLCSessionStarted?.Invoke(this, session);

            return(session);
        }