Exemplo n.º 1
0
        public void StartConnect(IDocument document, ConnectionItem connectionItem)
        {
            var connection = PrepareConnection(document, connectionItem);

            ConnectingStarted.Invoke(null, new DocumentConnectionEvent(document, Connections[document]));
            connection.StartOpen();
        }
Exemplo n.º 2
0
        public async Task Connect(CancellationToken cancellationToken = default)
        {
            retry = true;
            int cooldown = 1000;

            ConnectingStarted?.Invoke(this, new EventArgs());
            while (true)
            {
                try
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    cancellationToken.Register(CancelConnection);
                    logger.LogInformation($"Connecting to {uri}...");
                    await connection.StartAsync(cancellationToken);

                    logger.LogInformation($"Connected to {uri}");
                    Connected?.Invoke(this, new EventArgs());
                    return;
                }
                catch (HttpRequestException)
                {
                    logger.LogWarning($"Connection to {uri} failed. Waiting {cooldown} ms before retrying");
                    await Task.Delay(cooldown);

                    cooldown = Math.Min(60000, cooldown * 2);
                }
                catch (OperationCanceledException)
                {
                    logger.LogDebug($"Connection to {uri} aborted");
                    break;
                }
            }
        }
        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);
        }