TlsException: Ошибка рукопожатия после отправки множества веб-запросов

Вопрос или проблема

После того как я отправляю около 1500-1700 веб-запросов (это всегда в этом диапазоне), я получаю следующую ошибку:

TlsException: Handshake failed - код ошибки: UNITYTLS_INTERNAL_ERROR, результат проверки: UNITYTLS_X509VERIFY_NOT_DONE

Перезапуск Unity “обновляет” квоту, и я могу отправить примерно такое же количество запросов снова.

Я создаю веб-скрейпер и мне нужно отправить около 14000 запросов.
Между каждым запросом есть задержка, и я отправляю максимум 5 одновременно, чтобы избежать перегрузки сервера.

Я также попробовал следующий сайт для тестирования, но получил ту же ошибку:
https://httpbin.org/

Вот мой HttpClient:

private static readonly Lazy<HttpClient> httpClient = new(() => new HttpClient(new HttpClientHandler
        {
            ServerCertificateCustomValidationCallback = (_, _, _, _) => true,
            ClientCertificateOptions = ClientCertificateOption.Automatic,
            SslProtocols = SslProtocols.None
        })
        {
            BaseAddress = new Uri("https://yugioh.fandom.com/"),
            Timeout = TimeSpan.FromSeconds(15),
            DefaultRequestHeaders =
            {
                ConnectionClose = true
            }
        });

Изменение настроек в HttpClient (или отсутствие пользовательских настроек вообще) не исправляет проблему.

Я читал, что UnityWebRequest может не иметь этих проблем, но его можно вызывать только из основного потока, и я не хочу перепроектировать все, чтобы использовать Корутины.

Ответ или решение

При возникновении ошибки TlsException: Handshake failed - error code: UNITYTLS_INTERNAL_ERROR, verify result: UNITYTLS_X509VERIFY_NOT_DONE после отправки большого количества веб-запросов, вероятно, проблема заключается в выходе за пределы определённого лимита соединений или ресурсов, связанных с обработкой TLS в Unity.

Вот несколько шагов, которые могут помочь решить эту проблему:

1. Уменьшите количество параллельных запросов

Хотя у вас уже есть ограничение на 5 параллельных запросов, стоит попробовать уменьшить это число до 2 или даже 1, чтобы проверить, улучшит ли это ситуацию. Это может уменьшить нагрузку на сервер и снизить вероятность ошибок на стороне Unity.

2. Увеличьте интервал между запросами

Если вы уже добавили задержку между запросами, попробуйте увеличить её до нескольких секунд. Это может помочь избежать перегрузки на сервере и улучшить стабильность соединений.

3. Отключите ConnectionClose

Обратите внимание на то, что установка ConnectionClose в true может привести к закрытию соединений, прежде чем они будут обработаны должным образом. Попробуйте удалить эту строку, чтобы Unity могла управлять соединениями более эффективно:

DefaultRequestHeaders =
{
    // ConnectionClose = true  // Удалите или закомментируйте эту строку
}

4. Используйте HttpClient более эффективно

Рекомендуется использовать общий экземпляр HttpClient для всех запросов, чтобы уменьшить накладные расходы на создание соединений. Ваш текущий подход с Lazy<HttpClient> это делает, и это хорошо.

5. Обработка ошибок и повторные попытки

Имейте в виду, что иногда запросы могут завершаться неудачей из-за временных проблем на сервере или сетевых неполадок. Реализуйте механизм повторных попыток для обработки неудачных запросов:

async Task<string> SendRequestWithRetriesAsync(string url, int maxRetries = 3)
{
    for (int i = 0; i < maxRetries; i++)
    {
        try
        {
            return await httpClient.Value.GetStringAsync(url);
        }
        catch (TlsException ex)
        {
            // Логируйте или обрабатывайте ошибку
            Debug.Log($"Ошибка при отправке запроса: {ex.Message}. Попробуйте повторить попытку {i + 1}/{maxRetries}");
        }
    }

    throw new Exception("Максимальное количество повторов исчерпано");
}

6. Переключение на UnityWebRequest

Хотя вы упомянули, что не хотите переделывать код, учитывая специфику работы UnityWebRequest с корутинами, возможно, стоит рассмотреть этот вариант. Код на UnityWebRequest имеет улучшенную обработку TLS и, в некоторых случаях, будет более устойчивым к подобным ошибкам.

7. Рассмотрите возможность распределения нагрузки

Если это возможно, попробуйте разделить ваши запросы на несколько дней или временных периодов. Если вас не ограничивает время, это может помочь избежать ограничения на количество запросов, обрабатываемых за короткий промежуток времени.

Заключение

Если вышеописанные шаги не помогут, то следующая рекомендация – проанализировать возможность увеличить лимиты или параметры на стороне сервера (при наличии такой возможности) или обратиться в техническую поддержку Unity для более глубокой диагностики проблемы с обработкой TLS.

Оцените материал
Добавить комментарий

Капча загружается...