Как синхронизировать таймер клиентской веб-страницы с сервером - PullRequest
4 голосов
/ 19 февраля 2012

Как лучше всего синхронизировать время на веб-странице с сервером?

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

Моя проблема похожа на этот вопрос, но принятый ответ помогает, но не полностью отвечает моим проблемам: Как синхронизировать javascript-Обратный отсчет со временем сервера

Я использую Ajax после загрузки страницы, чтобы получить время сервера, но гарантирую ли я в течение 15 минут, что обратный отсчет закончится в одно и то же время для каждого клиента?

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

Ответы [ 3 ]

9 голосов
/ 14 августа 2012

Принятый ответ хорош и вдохновил меня, когда я написал библиотеку для решения этой проблемы.Библиотека дает более точные ответы, рассматривая время самой загрузки, а не всю страницу (как было сделано с помощью performance.timing выше), а затем получает еще большую точность, выполняя последовательность из 10 запросов XMLHttpRequest.Кроме того, учитывая вашу вторую проблему, моя библиотека не игнорирует миллисекунды (как и принятый ответ).

Библиотека называется ServerDate и доступна бесплатно.

Вот часть README:

Вы можете использовать ServerDate, как если бы вы использовали функцию Date или один из ее экземпляров, например:

> ServerDate()
"Mon Aug 13 2012 20:26:34 GMT-0300 (ART)"

> ServerDate.now()
1344900478753

> ServerDate.getMilliseconds()
22

Существует также новыйметод для получения точности оценки ServerDate часов сервера (в миллисекундах):

> ServerDate.toLocaleString() + " ± " + ServerDate.getPrecision() + " ms"
"Tue Aug 14 01:01:49 2012 ± 108 ms"

Вы можете увидеть разницу между часами сервера и часами браузеров в миллисекундах:

> ServerDate - new Date()
39
4 голосов
/ 19 февраля 2012

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

Пример:

var tsp = new Date('Sun Feb 19 2012 17:55:14 GMT+0100 (CET)'); // "Timestamp"

window.onload = function() {
    var performance = window.performance || window.mozPerformance || window.msPerformance || window.webkitPerformance || {};
    tsp.setTime(tsp.getTime() + performance.timing.loadEventStart - performance.timing.navigationStart
    // after window.onload, you're sync with the server

    // Example of timer:
    setInterval(function() {
        tsp.setSeconds(tsp.getSeconds() + 1);
        document.title = tsp.toString();
    }, 1000); // 1000 ms = timer may be off by 500ms.
};

Дополнительную информацию об этом объекте можно найти в статье MDN .
Демоверсия предоставляется здесь .

2 голосов
/ 19 февраля 2012

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

Я не уверен, насколько хорошо websockets работает вместе с PHP.

Я когда-либо использовал socket.io только вместе с узлом JS. С этим решением было бы тривиально установить тайм-аут на стороне сервера и уведомить всех клиентов одновременно, когда оно завершится. Он автоматически определяет поддержку браузера и выбирает метод, который лучше всего подходит для данного браузера.

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

...