Как можно угадать скорость клиентского подключения

Мне нужно сделать динамическое решение о весе содержимого для отправки клиенту на основе его скорости соединения.

То есть: если клиент использует мобильное устройство с 3G (или более медленным) соединением, я отправляю ему/ей легкий контент. Если он использует WiFi или более быстрое соединение, я посылаю ему/ей полный контент.

Я попытался измерить время между перезагрузками, отправив клиенту заголовок Location: myurl.com (с некоторой информацией о клиенте, чтобы идентифицировать его). Это работает на настольных браузерах и некоторых мобильных браузерах (например, Obigo), но это не работает на мини-(прокси) браузерах, таких как Opera Mini или UCWeb. Эти браузеры возвращают время соединения между моим сервером и прокси-сервером, а не мобильным устройством.

То же самое происходит, если я попытаюсь перезагрузить страницу тегом <meta> или Javascript document.location.

Есть ли способ обнаружить или измерить скорость клиентского соединения, или он использует 3G или Wi-Fi и т.д., который работает в мини-браузерах (т.е. я могу определить медленное соединение через мини-браузер)

Ответ 1

Я думаю, вы не должны измерять скорость или пропускную способность.

Первое предположение может быть браузером клиента. Существует много разных браузеров для компьютеров, но они, как правило, не совпадают с браузерами для мобильных устройств.

Легко проверить, что браузер использует ваши пользователи.

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

Ответ 2

Это отличный вопрос. Я не сталкивался с любыми методами оценки скорости клиента из браузера раньше. Однако у меня есть идея; Я не задумывался над этим несколько минут, но, надеюсь, это даст вам некоторые идеи. Кроме того, пожалуйста, простите мою многословие:

Во-первых, при рассмотрении производительности клиент-сервер необходимо учитывать две вещи: пропускную способность и задержку. Как правило, мобильный клиент будет иметь низкую пропускную способность (и, следовательно, низкую пропускную способность) по сравнению с настольным клиентом. Кроме того, мобильное клиентское соединение может быть более подверженным ошибкам и, следовательно, иметь более высокую задержку. Однако в моем ограниченном опыте высокая латентность не означает низкую пропускную способность. И наоборот, низкая латентность не означает высокую пропускную способность.

Таким образом, вам может потребоваться различать латентность и пропускную способность. Предположим, что клиент отправляет временную метку (пусть ее называют "А" ) с каждым HTTP-запросом, а сервер просто возвращает ее обратно. Затем клиент может вычесть эту возвращенную метку времени с ее текущим временем, чтобы оценить, сколько времени потребовалось для совершения поездки туда и обратно. Это время включает в себя почти все, включая задержку сети, и время, необходимое серверу для полного получения вашего запроса.

Теперь предположим, что сервер отправляет обратно временную метку "A" сначала в заголовках ответов перед отправкой всего тела ответа. Также предположим, что вы можете поэтапно читать ответ сервера (например, неблокирующий IO. Существует множество способов сделать это.) Это означает, что вы можете получить свою эхо-метку времени перед чтением ответа сервера. На этом этапе клиентское время "B" минус временная метка запроса "A" является приблизительной задержкой. Сохраните это, вместе с клиентом время "B" .

Как только вы закончите читать ответ, количество данных в теле ответа, деленное на новое время клиента "C" минус предыдущее клиентское время "B" , является приблизительным значением вашей пропускной способности. Например, предположим, что C - B = 100 мс, и вы прочитали 100 килобайт данных, тогда ваша пропускная способность составляет 10 кбит/с.

Вновь соединения мобильных клиентов подвержены ошибкам и имеют тенденцию к изменениям со временем. Таким образом, вы, вероятно, не хотите проверять пропускную способность один раз. Фактически, вы можете также измерить пропускную способность каждого ответа и сохранить скользящую среднюю пропускной способности клиента. Это уменьшит вероятность того, что необычно плохая пропускная способность по одному запросу приведет к понижению качества клиента или наоборот.

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

EDIT: прояснили некоторые вещи и добавили пример пропускной способности.

Ответ 3

Первое: работа над SSL (HTTPS) позволит избежать многих прокси-ошибок. Это также остановит такие вещи, как сжатие (что может ускорить загрузку HTML, CSS и т.д., Но не поможет для уже сжатых данных).

Время загрузки страницы - это латентность + (ширина × × размер). Даже если время ожидания неизвестно, измерение небольшого файла и большого файла может дать вам пропускную способность:

Let L be latency, B be bandwidth, both unknown.
Let t₁ and t₂ be the measured download times.
In this example, the two sizes are 128k and 256k.

t₁ = L + B × 128                             // sure would be nice if SO had Τεχ
t₂ = L + B × 256
t₂ - t₁ = (L + B × 256) - (L + B × 128)
        = L + B × 256 - L - B × 128
        = 256(B) - 128(B)
        = 128(B)

Итак, вы можете видеть, что если вы разделите разницу во времени на разницу в размерах страниц, вы получите пропускную способность. Взятие одного измерения может дать странные результаты из-за задержки и пропускной способности, которые не являются постоянными. Повторяя несколько раз (и выкидывая выбросы и абсурдные (например, отрицательные) значения) будут сходиться по истинной средней полосе пропускания.

Вы можете делать эти измерения на JavaScript легко, в фоновом режиме, используя любую инфраструктуру AJAX. Получите текущее время, отправьте запрос, а не часы, когда получен ответ. Сами запросы должны быть одного размера, поэтому накладные расходы на отправку запросов являются лишь частью задержки. Вероятно, вы захотите использовать разные хосты, чтобы победить постоянные соединения. Либо это, либо настроить ваш сервер для отказа от постоянных подключений, но только к вашим тестовым файлам.

Я полагаю, что я немного злоупотребляю задержкой слова, он включает время для всех постоянных служебных сообщений (например, отправки запроса). Ну, его латентность от желания получить первый байт полезной нагрузки.

Ответ 4

Это что-то, что вы можете обнаружить на стороне клиента? Если вам нужно обойти прокси-серверы, вы всегда можете узнать тип подключения на стороне клиента и отправить его обратно. Другим методом было бы загрузить файл на стороне клиента через какой-либо скриптовый механизм, записать байты в секунду и вернуть эту информацию на сервер.

Ответ 5

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

Как насчет простого запроса ajax, который запрашивает URL-адрес для контента? Просто запишите временную серверную часть первого запроса с IP-адресом клиента, где-нибудь (файл или базу данных), а затем сравните его со временем запроса с клиентского javascript и доставьте URL-адрес после сравнения двух раз произвольное "быстрое" или "медленное" ограничение времени и доставить URL-адрес для содержимого соответствующей скорости.