/// <exception cref="InvalidOperationException">The client must be logged in before connecting.</exception>
        /// <exception cref="NotSupportedException">This client is not configured with WebSocket support.</exception>
        internal override async Task ConnectInternalAsync()
        {
            if (LoginState != LoginState.LoggedIn)
            {
                throw new InvalidOperationException("The client must be logged in before connecting.");
            }
            if (WebSocketClient == null)
            {
                throw new NotSupportedException("This client is not configured with WebSocket support.");
            }

            RequestQueue.ClearGatewayBuckets();

            //Re-create streams to reset the zlib state
            _compressed?.Dispose();
            _decompressor?.Dispose();
            _compressed   = new MemoryStream();
            _decompressor = new DeflateStream(_compressed, CompressionMode.Decompress);

            ConnectionState = ConnectionState.Connecting;
            try
            {
                _connectCancelToken?.Dispose();
                _connectCancelToken = new CancellationTokenSource();
                if (WebSocketClient != null)
                {
                    WebSocketClient.SetCancelToken(_connectCancelToken.Token);
                }

                if (!_isExplicitUrl)
                {
                    var gatewayResponse = await GetGatewayAsync().ConfigureAwait(false);

                    _gatewayUrl = $"{gatewayResponse.Url}?v={DiscordConfig.APIVersion}&encoding={DiscordSocketConfig.GatewayEncoding}&compress=zlib-stream";
                }
                await WebSocketClient.ConnectAsync(_gatewayUrl).ConfigureAwait(false);

                ConnectionState = ConnectionState.Connected;
            }
            catch
            {
                if (!_isExplicitUrl)
                {
                    _gatewayUrl = null; //Uncache in case the gateway url changed
                }
                await DisconnectInternalAsync().ConfigureAwait(false);

                throw;
            }
        }