2015-12-20 8 views
-2

Поместите компонент TIdHTTP и компонент TIdSSLIOHandlerSocketOpenSSL на форму VCL.TIdHTTP.Получите очень медленно с HTTPS-адресами

Не назначайте ничего для IdHTTP1.IOHandler.

Тогда получите HTML от HTTP URL, например:

sHTML := IdHTTP1.Get('http://www.pixar.com'); 

• Это очень быстро и хорошо работает.

Затем назначьте IdSSLIOHandlerSocketOpenSSL1 на IdHTTP1.IOHandler.

Затем введите ssleay32.dll и libeay32.dll в каталог приложения.

Тогда получите HTML от HTTPS URL, например:

sHTML := IdHTTP1.Get('https://www.youtube.com/watch?v=CB1Pukr0nFQ'); 

• Это очень медленно и занимает почти 4 секунды, чтобы получить HTML (!).

Итак, почему это так медленно с URL-адресом HTTPS и является самым быстрым способом получения HTML-кода как из HTTP, так и из HTTPS-адресов?

ответ

2

Шифрование и дешифрование содержимого HTML имеет больше накладных расходов, чем передача незашифрованного контента.

Существует также накладные расходы при установлении безопасного сеанса с сервером до того, как контент может быть запрошен и передан (запрос и ответ зашифрованы).

Кроме того, в то время, когда запрос HTTPS выполняется, если OpenSSL еще не загружен, в загрузке и инициализации библиотек OpenSSL возникают накладные расходы.

Кроме того, вы вызываете версию TIdHTTP.Get(), которая возвращает String, поэтому все загруженные данные должны быть буферизованы в памяти и затем декодированы в кодировку UTF-16. Чем больше HTML, тем больше расшифровки необходимо выполнить.

Все эти накладные расходы складываются.

Некоторые вещи, которые вы можете сделать, чтобы уменьшить некоторые накладных расходов являются:

  1. предварительного натяга OpenSSL заранее (Indy имеет LoadOpenSSLLibrary() функцию).

  2. убедитесь, что вы повторно с помощью HTTP-соединений к одному серверу, используя одни и те же TIdHTTP/TIdSSLIOHandlerSocketOpenSSL объектов, и позволяет HTTP Keep-alives, установив TIdHTTP.Request.Connection свойство keep-alive и/или установки TIdHTTP.ProtocolVersion свойство pv1_1 (keep-alive - это поведение по умолчанию в HTTP 1.1, но не в 1.0).

  3. В зависимости от того, что вы собираетесь делать с загруженным HTML, вы можете загрузить его в TStream вместо String.Таким образом, TIdHTTP.Get() пропустит шаги кеширования и кодировки кодировки, все, что будет загружено, будет сохранено как есть непосредственно к вашим предоставленным TStream. Если вам вообще не нужен HTML-код, вы можете передать nilTStream, чтобы сообщить Get() не кэшировать/обрабатывать загруженные данные вообще.

Кроме того, проверьте, чтобы увидеть, если отправив запрос на YouTube фактически генерировать только один запрос/ответ, и не может быть сервер, используя HTTP перенаправления, которые вызывают дополнительные запросы, которые будут отправлены, таким образом, принимая больше времени, чтобы достичь окончательный контент (см. если инициируется событие TIdHTTP.OnRedirect). Запросить домашнюю страницу Pixar вряд ли это сделает.

+0

Итак, как браузер делает это так быстро? Когда я открываю Youtube в браузере, я мгновенно получаю страницу. – user1580348

+0

Различные браузеры используют разные реализации SSL/TLS и делают разные вещи. Кроме того, у браузеров также намного больше вычислительной мощности. Вы сравниваете яблоки с апельсинами здесь. В любом случае, я протестировал URL-адреса, которые вы предоставили, используя последний снимок SVN для Indy, и требуется 'TIdHTTP.Get()' всего 1,4 секунды для запроса, загрузки и декодирования данных YouTube. И это учитывает все накладные расходы, о которых я говорил. –