Esempio n. 1
0
        private async Task ConnectCore()
        {
            ConnectStatus = Status.Connecting;
            var now = DateTimeOffset.UtcNow;

            if (now - _lastAuthTime > AuthExpire)
            {
                (string url, string accessToken) = await GetAuth();

                if (string.IsNullOrEmpty(url) || string.IsNullOrEmpty(accessToken))
                {
                    throw new ArgumentNullException("url or accesstoken is null");
                }

                if (Connection != null)
                {
                    Connection.Closed -= OnClosed;
                    // 1. dispose the old connection first
                    await Connection.DisposeAsync();

                    Connection = null;
                }

                var connection = new HubConnectionBuilder()
                                 .WithUrl(url, options =>
                                          //.WithUrl("http://localhost:8080/client?hub=gamehub", options =>
                {
                    options.AccessTokenProvider = () => Task.FromResult(accessToken);
                    options.CloseTimeout        = TimeSpan.FromSeconds(15);
                    options.Transports          = HttpTransportType.WebSockets;
                    options.SkipNegotiation     = true;
                })
                                 //.AddMessagePackProtocol()
                                 .Build();

                connection.Closed += OnClosed;

                connection.On("Connected", () =>
                {
                    ConnectStatus = Status.Connected;
                    Interlocked.Increment(ref ConnectStats.SuccessCount);

                    var elapsed = ConnectStats.SetElapsed(_lastConnectTime);
                });

                connection.On <MessageBody>("PerformanceTest", message =>
                {
                    Interlocked.Increment(ref SendMessageStats.ReceivedCount);
                    SendMessageStats.SetElapsed(message.CreatedTime);
                });

                // set the auth time after the connection is built
                _lastAuthTime = DateTime.UtcNow;
                Connection    = connection;
            }

            _lastConnectTime = DateTime.UtcNow;
            Interlocked.Increment(ref ConnectStats.TotalCount);
            await Connection.StartAsync();
        }
Esempio n. 2
0
        public async Task Connect()
        {
            if (IsConnected || IsConnecting)
            {
                return;
            }
            IsConnecting = true;

            await Task.Yield();

            _lastAuthTime = DateTime.Now;

            (string url, string accessToken) = GetAuth();

            if (string.IsNullOrEmpty(url) || string.IsNullOrEmpty(accessToken))
            {
                throw new ArgumentNullException("url or accesstoken is null");
            }

            connection = new HubConnectionBuilder()
                         .WithUrl(url, options =>
            {
                options.AccessTokenProvider = () => Task.FromResult(accessToken);
                options.CloseTimeout        = TimeSpan.FromSeconds(15);
                options.Transports          = HttpTransportType.WebSockets;
                options.SkipNegotiation     = true;
            })
                         //.AddMessagePackProtocol()
                         .Build();

            connection.Closed += ex => {
                IsConnected  = false;
                IsConnecting = false;
                return(RetryConnect(ex));
            };

            connection.On("Connected", () => {
                Interlocked.Increment(ref ConnectStats.SuccessCount);

                var elapsed = ConnectStats.SetElapsed(lastConnectTime);

                IsConnected  = true;
                IsConnecting = false;
            });

            connection.On <MessageBody>("PerformanceTest", message =>
            {
                Interlocked.Increment(ref SendMessageStats.ReceivedCount);
                SendMessageStats.SetElapsed(message.CreatedTime);
            });

            await ConnectCore();
        }
Esempio n. 3
0
        private async Task RetryConnect(Exception ex)
        {
            if (!_connectLock.Wait(0))
            {
                // someone is already connecting
                return;
            }

            try
            {
                if (ex != null)
                {
                    ConnectStats.AddException(ex);
                    Interlocked.Increment(ref ConnectStats.ErrorCount);
                }

                var reconnectNow = DateTime.UtcNow;
                while (true)
                {
                    try
                    {
                        // delay a random value < 3s
                        await Task.Delay(new Random((int)Stopwatch.GetTimestamp()).Next(MinReconnectWaitMilliseconds, MaxReconnectWaitMilliseconds));
                        await ConnectCore();

                        RecoverStats.SetElapsed(reconnectNow);
                        Interlocked.Increment(ref RecoverStats.SuccessCount);
                        break;
                    }
                    catch (Exception e)
                    {
                        RecoverStats.AddException(e);

                        Interlocked.Increment(ref RecoverStats.ErrorCount);
                        Interlocked.Increment(ref ConnectStats.ErrorCount);
                    }
                }
            }
            finally
            {
                _connectLock.Release();
            }
        }
Esempio n. 4
0
        private async Task RetryConnect(Exception ex)
        {
            ConnectStats.AddException(ex);

            Interlocked.Increment(ref ConnectStats.ErrorCount);
            var reconnectNow = DateTime.Now;

            while (true)
            {
                try
                {
                    await Task.Delay(new Random((int)Stopwatch.GetTimestamp()).Next(300, 20000));

                    if (DateTime.Now > _lastAuthTime.AddMinutes(50))
                    {
                        // Reauth
                        await Connect();
                    }
                    else
                    {
                        // direct connect
                        await ConnectCore();
                    }

                    RecoverStats.SetElapsed(reconnectNow);
                    Interlocked.Increment(ref RecoverStats.SuccessCount);
                    break;
                }
                catch (Exception e)
                {
                    RecoverStats.AddException(e);

                    Interlocked.Increment(ref RecoverStats.ErrorCount);

                    Interlocked.Increment(ref ConnectStats.NotSentCount);
                    // another round after 300
                }
            }
        }