/// <summary>
        ///     Send HTTP request
        /// </summary>
        /// <param name="request">HTTP request</param>
        /// <param name="timeout">HTTP request timeout (default is 1 minute)</param>
        /// <returns>HTTP request Task</returns>
        public Task <HttpNetworkResponse> SendRequestAsync(HttpNetworkRequest request, TimeSpan?timeout = null)
        {
            timeout ??= TimeSpan.FromMinutes(1);

            _tcs           = new TaskCompletionSource <HttpNetworkResponse>();
            NetworkRequest = request;

            // Check if the HTTP request is valid
            if (NetworkRequest.IsEmpty || NetworkRequest.IsErrorSet)
            {
                SetPromiseError("Invalid HTTP request!");
                return(_tcs.Task);
            }

            if (!IsConnected)
            {
                // Connect to the Web server
                if (!ConnectAsync())
                {
                    SetPromiseError("Connection failed!");
                    return(_tcs.Task);
                }
            }
            else
            {
                // Send prepared HTTP request
                if (!base.SendRequestAsync())
                {
                    SetPromiseError("Failed to send HTTP request!");
                    return(_tcs.Task);
                }
            }

            void TimeoutHandler(Object state)
            {
                // Disconnect on timeout
                OnReceivedResponseError(NetworkResponse, "Timeout!");
                NetworkResponse.Clear();
                DisconnectAsync();
            }

            // Create a new timeout timer
            _timer ??= new Timer(TimeoutHandler, null, Timeout.Infinite, Timeout.Infinite);

            // Start the timeout timer
            _timer.Change((Int32)timeout.Value.TotalMilliseconds, Timeout.Infinite);

            return(_tcs.Task);
        }
        protected override void OnDisconnected()
        {
            // Disconnect WebSocket
            if (webSocketNetwork.WsHandshaked)
            {
                webSocketNetwork.WsHandshaked = false;
                OnWsDisconnected();
            }

            // Reset WebSocket upgrade HTTP request and response
            NetworkRequest.Clear();
            NetworkResponse.Clear();

            // Clear WebSocket send/receive buffers
            webSocketNetwork.ClearWsBuffers();
        }