Как определить латентность удаленного сервера через браузер
Я запускаю пару игровых туннельных серверов и хотел бы иметь страницу, на которой клиент может запустить пинг на всех серверах и узнать, какой из них наиболее отзывчив. Насколько я вижу, похоже, что нет подходящего способа сделать это в JavaScript, но я думал, знает ли кто-нибудь о способе сделать это во флэш-памяти или какой-нибудь другой технологии браузера клиента?
Ответы
Ответ 1
Большинство технологий апплетов, включая Javascript, применяют политику одинакового происхождения. Возможно динамическое добавление элементов DOM, таких как изображения, и сбор информации о времени с помощью обработчика события onload.
псевдопользователей-код
for (server in servers) {
var img = document.createElement('IMG');
server.startTime = getCurrentTimeInMS();
img.onload=function() { server.endTime = getcurrentTimeInMS(); }
img.src = server.imgUrl;
}
Затем подождать подходящее время и проверить время для каждого объекта сервера. Повторяйте по мере необходимости и вычислите средние значения, если хотите. Я не уверен, какую точность вы можете ожидать.
Недостатки:
- Возможно, вы используете неправильный инструмент для работы. Браузер не оборудован для такого рода приложений.
- Возможно, это довольно неточно.
- Если запрашиваемый вами ресурс кэшируется, он не даст вам желаемых результатов, но вы можете обойти это, изменяя URL каждый раз.
- Это интенсивность полосы пропускания по сравнению с обычным пингом. Сделайте изображение маленьким, например, файл spacer.gif.
- Время зависит не только от латентности удаленного сервера, но и от полосы пропускания этого сервера. Это может быть более или менее полезной мерой, но важно отметить, что это не просто латентность.
- Вам нужно иметь возможность обслуживать HTTP-запросы с разных серверов, и, в решающей степени, каждый сервер должен обслуживать тот же самый ресурс (или ресурс той же длины). Условия на сервере могут влиять на время отклика, например, если один сервер сжимает данные, а другой - нет.
Ответ 2
Перед вызовом на сервер запишите время Javascript:
var startTime = new Date();
Загрузите изображение с сервера:
var img = new Image()
img.onload = function() {
// record end time
}
img.src = "http://server1.domain.com/ping.jpg";
Как только запрос будет завершен, запишите время снова. (Учитывая, конечно, что запрос не тайм-аут.)
var endTime = new Date();
Ваш пинг в миллисекундах:
var ping = endTime. getTime() - startTime.getTime();
Ответ 3
Все, что вам действительно нужно - это время от начала соединения до момента первого изменения readystate...
function getPing() {
var start;
var client = getClient(); // xmlhttprequest object
client.onreadystatechange = function() {
if (client.readyState > 0) {
pingDone(start); //handle ping
client.onreadystatechange = null; //remove handler
}
}
start = new Date();
client.open("HEAD", "/ping.txt"); //static file
client.send();
}
function pingDone(start) {
done = new Date();
ms = done.valueOf() - start.valueOf();
alert(ms + "ms ping time");
}
function getClient() {
if (window.XMLHttpRequest)
return new XMLHttpRequest();
if (window.ActiveXObject)
return new ActiveXObject('MSXML2.XMLHTTP.3.0');
throw("No XMLHttpRequest Object Available.");
}
Ответ 4
Здесь <iframe>
:
http://magnetiq.com/exports/server_ping.png
Создайте таблицу (не обязательно в буквальном <table>
смысле) с двумя столбцами. В первом столбце будут указаны имена серверов (и, возможно, ссылки на них). Во втором столбце есть iframe, которые загружают пробные документы с соответствующих серверов. Каждый пробный документ выполняет это по первому запросу на выборку:
- Получить текущее системное время
- Сделайте переадресацию (302) ко второму пробному документу при передаче системного времени в качестве параметра запроса
- Второй пробный документ считывает текущее системное время, вычисляет дельта от начального чтения, которое было передано ему, и просто отображает его большими жирными буквами. Эта дельта - это время, необходимое серверу для ответа клиенту с ответом на перенаправление плюс время, затрачиваемое клиентом на второй запрос на перенаправление. Это не совсем "пинг", но это сопоставимая мера относительной задержки клиента с каждым сервером. Фактически, это "обратный пинг" от сервера к клиенту.
Вы будете использовать iframes, не нарушая политику того же домена, потому что не пытайтесь вообще манипулировать содержимым iframe. Игрок будет просто видеть ценности своими глазами, и вы будете полагаться на пользователя, который смотрит на цифры и нажимая на ссылку сервера, которая имеет наибольший смысл.
Ответ 5
Если вы говорите о запуске какой-либо клиентской стороны, я не уверен, что это возможно из-за соображений безопасности.
Возможно, лучшим вариантом будет апплет java, но опять же это нужно проверить против локальной политики безопасности.
Если я попытаюсь подумать о каком-то взломе в JS, чтобы сделать это, возможно, вы можете попытаться отправить асинхронный запрос с функцией обратного вызова, которая измеряет миллисекунды, которые она приняла, но это просто не в моей голове.
Ответ 6
Не так сложно измерить время отклика сервера во Flash.
Перед обращением к удаленным серверам Flash должен запросить файл политики.
Местоположение по умолчанию для такого файла политики находится в корневой папке сервера:/crossdomain.xml
(Вы можете легко найти информацию о формате файла crossdomain)
Так как такой файл необходим в любом случае, почему бы не использовать его для измерения времени отклика сервера? Загрузите сам файл вместо изображения и определите время, затраченное на использование getTimer().
Это даст вам хорошую оценку HTTP-соединений.
Но если вы имеете дело с игровыми серверами, вы можете напрямую проверить скорость соединения TCP. Для этого вам понадобится использовать flash.net.Socket
Вы также должны сначала попросить файл политики, выполнив:
Security.loadPolicyFile( "XMLSocket://server.domain.com: 5342" );
Где 5342 представляет номер вашего сервера, где он должен отвечать правильной строкой политики XML.
После подключения сокета любой запрос/ответ позволит вам измерять время отклика сервера.
Ответ 7
Имейте в виду, что латентность будет по крайней мере вдвое больше того, что вы увидите для ping, если вы в конечном итоге сделаете TCP-запрос для измерения задержки, потому что вам понадобится трехстороннее квитирование и пакет завершения как минимум (две круглые поездки, а не одна). Если вы делаете HTTP-запросы, постарайтесь свести заголовки к минимуму. Достаточно длинный заголовок (из-за чат-сервера, или файлов cookie и т.д. На клиенте) может добавлять дополнительные раунды в микс, отбрасывая ваши измерения.
Ответ 8
Проблема с "файловыми пинсами" заключается в том, что вы будете оценивать ответ HTTP-сервера, тогда как ваш целевой ресурс для игр, которые вы обслуживаете, может иметь совсем другое поведение и, следовательно, различную задержку.
Просто идея не в синей, может быть, даже нереальной в зависимости от реального контекста:
но было бы интересно сделать сервер script на основе короткой последовательности задач, обычно выполняемых серверами во время игры (например, открытие RTMP-соединения, получение информации, отправка его обратно). В зависимости от общего количества серверов вы можете почти открывать их одновременно и определять первый ответ как победитель (вычитая время, которое ваш клиент должен самостоятельно обрабатывать каждый запрос).
Конечно, это довольно дорогостоящий метод, говорящий на стороне сервера, но, по крайней мере, вы надеетесь получить надежный результат (суммарное количество серверов и сетей). Даже если это займет пару секунд, чтобы оценить, это будет часть доли полной приятной игры.