powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / HTML, JavaScript, VBScript, CSS [игнор отключен] [закрыт для гостей] / JS, правильные серверные часы
10 сообщений из 10, страница 1 из 1
JS, правильные серверные часы
    #38894483
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нужно выводить на странице дату и время сервера, обновляемые каждую секунду.
Время от времени (раз в минуту или раз в 5 минут) с сервера запрашивается время (timestamp), чтобы обнулить отклонения.
Есть функция _query(callback), делающая асинхронный запрос и вызывающая callback-функцию с передачей в нее JSON-объекта с данными (callback-функция вызывается только в случае успешного получения ответа от сервера), json.clock — это timestamp сервера.
Я сделал так:
Код: javascript
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
// <body onload="refreshClock()">

var clock_base = null;
var clock_delta = null;
function refreshClock(json)
{
        function update(timestamp)
        {
                var dt = new Date(timestamp * 1000);
                document.getElementById('clock-date').innerHTML = dt.format('%D.%M.%Y');
                document.getElementById('clock-time').innerHTML = dt.format('%h:%m:%s');
                return dt;
        }
        if (typeof(json)=='undefined' || json===null)
        {
                if (!clock_base || clock_delta > 10)
                {
                        _query(refreshClock);
                        setTimeout(refreshClock,1000);
                        return true;
                }
                clock_delta++;
                update(clock_base+clock_delta);
                setTimeout(refreshClock,1000);
                return true;
        }
        clock_base = json.clock;
        clock_delta = 0;
        update(clock_base+clock_delta);
        setTimeout(refreshClock,1000);
        return true;
}



Но почему-то время на странице отображается неправильное — вначале увеличивается по 2 секунды, а затем изменения вообще непонятны.

________________________
Мы смотрим с оптимизмом...
...в оптический прицел.
...
Рейтинг: 0 / 0
JS, правильные серверные часы
    #38894513
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В таком виде часы тикают нормально:
Код: javascript
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
function refreshClock(json)
{
        document.getElementById('clock-date').innerHTML = clock_base+'/'+clock_delta;
        function update(timestamp)
        {
                var dt = new Date(timestamp * 1000);
                //document.getElementById('clock-date').innerHTML = dt.format('%D.%M.%Y');
                document.getElementById('clock-time').innerHTML = dt.format('%h:%m:%s');
                return dt;
        }
        if (typeof(json)=='undefined' || json===null)
        {
                if (!clock_base || clock_delta > 100000000)
                {
                        _query(refreshClock);
                }
                if (clock_base)
                {
                        clock_delta++;
                        update(clock_base+clock_delta);
                        setTimeout(refreshClock,1000);
                }
                return true;
        }
        clock_base = json.clock;
        clock_delta = 0;
        update(clock_base+clock_delta);
        setTimeout(refreshClock,1000);
        return true;
}


В такой реализации серверный timestamp запрашивается при загрузке страницы один раз и впоследствии часы тикают автономно (clock_delta > 100000000).
Но как только я включаю периодическую «подводку» часов (clock_delta > 10), начинаются непонятности — вначале время увеличивается на две секунды, а после 10 секунд начинают ходить хаотично, страница начинает потреблять ресурсы и через некоторое время браузер ее прибивает.
...
Рейтинг: 0 / 0
JS, правильные серверные часы
    #38894535
kunaksergey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Alibek B.,
А для чего такой изврат? Один раз возьмите время с сервера, высчитайте разницу между timestamp сервера и у вас.
...
Рейтинг: 0 / 0
JS, правильные серверные часы
    #38894560
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Страница может быть открыта долго, десятки часов, расхождения могут быть заметными.
Кроме того, если пользователь изменит часы на своем ПК, результат будет неадекватным.
Поэтому я бы не хотел ориентироваться на локальный таймстамп.
...
Рейтинг: 0 / 0
JS, правильные серверные часы
    #38894638
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Причину рекурсии вроде бы нашел — если clock_delta по какой-то причине не обнулялся, то ajax-запрос выполнялся каждую секунду.
Текущая версия функции такая:
Код: javascript
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
var clock_base;
var clock_delta;
var clock_wait;

function refreshClock(json)
{
        document.getElementById('clock-tag').innerHTML = clock_base+'/'+clock_delta+'/'+clock_wait;
        function update(timestamp)
        {
                var dt = new Date(timestamp * 1000);
                document.getElementById('clock-date').innerHTML = dt.format('%D.%M.%Y');
                document.getElementById('clock-time').innerHTML = dt.format('%h:%m:%s');
                return dt;
        }
        if (typeof(json)=='undefined' || json===null)
        {
                if (!clock_base || clock_delta > 10)
                {
                        if (!clock_wait)
                        {
                                clock_wait = true;
                                _query(refreshClock);
                        }
                }
                if (clock_base)
                {
                        clock_delta++;
                        update(clock_base+clock_delta);
                        setTimeout(refreshClock,1000);
                }
        }
        else
        {
                clock_wait = false;
                clock_base = json.clock;
                clock_delta = 0;
                update(clock_base+clock_delta);
                setTimeout(refreshClock,1000);
        }
        return true;
}


Теперь прогрессирующего потребления ресурсов нет.
Но часы все-равно тикают неправильно.

Первые 10 секунд часы ходят правильно.
Затем clock_delta сбрасывается на ноль.
Затем почему-то начинает увеличиваться не на 1, а на 2, и соответственно следующая корректировка часов (вызов _query) происходит не через 10 секунд, а через 5.
После этого clock_delta снова сбрасывается на ноль и начинает увеличиваться на 3 или 4 при каждом тике.

Никак не найду, где рекурсия осталась.
...
Рейтинг: 0 / 0
JS, правильные серверные часы
    #38894713
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Кажется нашел, в чем дело.
Асинхронный запрос срабатывает слишком быстро, функция refreshClock все еще выполняется, когда приходит ответ от сервера и она вызывается из _query.
В таком виде часы ходят нормально:
Код: javascript
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
function refreshClock(json)
{
        function update(timestamp)
        {
                var dt = new Date(timestamp * 1000);
                document.getElementById('clock-date').innerHTML = dt.format('%D.%M.%Y');
                document.getElementById('clock-time').innerHTML = dt.format('%h:%m:%s');
                return dt;
        }
        if (typeof(json)=='undefined' || json===null)
        {
                if (!clock_base || clock_delta > 10)
                {
                        if (!clock_wait)
                        {
                                clock_wait = true;
                                _query(refreshClock);
                                return false;
                        }
                }
                if (clock_base)
                {
                        clock_delta++;
                        update(clock_base+clock_delta);
                        setTimeout(refreshClock,1000);
                }
        }
        else
        {
                clock_wait = false;
                clock_base = json.clock;
                clock_delta = 0;
                update(clock_base+clock_delta);
                setTimeout(refreshClock,1000);
        }
        debug++;
        document.getElementById('clock-tag').innerHTML = clock_base+'/'+clock_delta+'/'+clock_wait+'/'+debug;
        return true;
}


Но при этом если вдруг _query не выполнится успешно, то часы остановятся.
Не подскажите, как это можно обойти?
...
Рейтинг: 0 / 0
JS, правильные серверные часы
    #38894746
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вообщем разбил на три функции, теперь все работает нормально.
Код: javascript
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
var clock = {'base':null,'delta':0,'wait':false,'sync':0};

function serverClockRefresh()
{
        if (!clock.base) return null;
        timestamp = clock.base + clock.delta;
        var dt = new Date(timestamp * 1000);
        document.getElementById('clock-date').innerHTML = dt.format('%D.%M.%Y');
        document.getElementById('clock-time').innerHTML = dt.format('%h:%m:%s');
        return dt;
}

function serverClockTick()
{
        if (!clock.wait && (!clock.base || clock.delta > 10))
        {
                clock.wait = true;
                _query(serverClockSync);
        }
        clock.delta++;
        serverClockRefresh();
        setTimeout(serverClockTick,1000);
        return true;
}

function serverClockSync(json)
{
        if (!json) return false;
        clock.sync++;
        clock.wait = false;
        clock.base = json.clock;
        clock.delta = 0;
        serverClockRefresh();
        return true;
}



Почему не работало в одной функции, я пока так и не понял.
...
Рейтинг: 0 / 0
JS, правильные серверные часы
    #38894770
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alibek
задача решается в одно дейстаие с использованием websocket
...
Рейтинг: 0 / 0
JS, правильные серверные часы
    #38894773
Alibek B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Каким образом?
...
Рейтинг: 0 / 0
JS, правильные серверные часы
    #38894805
kunaksergey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Alibek B.,
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
<html>
<script>
var delay=5*60*1000; //5мин
var xmlhttp = new XMLHttpRequest(); //объект request

var object = {
timeclient:function(){	date=new Date();return date.getTime(); } //текущее время
}

 function refreshTime(){
 	var dt=new Date(object.timeclient()+object.delta);
	document.getElementById('clock-time').innerHTML=dt.getHours()+"-"+dt.getMinutes()+"-"+dt.getSeconds();
 }


function getTime(){
	
 xmlhttp.open('GET', 'time.php?'+Math.random(), true);
 xmlhttp.onreadystatechange = function() {
 if (xmlhttp.readyState == 4) {
     if(xmlhttp.status == 200) {
           
           object.timeserver=xmlhttp.responseText; //время сервера
           object.delta=object.timeserver*1000-object.timeclient(); //разница
           setInterval("refreshTime()",1000); //вызываем каждую секунду          
           refreshTime();
         }
  }
};
xmlhttp.send(null);
}

setInterval("getTime()",delay); //вызываем каждые 5 минут
getTime();

</script>
<body>
<div id="clock-time"></div>
</body>
</html>


Но вообще это изврат
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / HTML, JavaScript, VBScript, CSS [игнор отключен] [закрыт для гостей] / JS, правильные серверные часы
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]