Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / HTML, JavaScript, VBScript, CSS [игнор отключен] [закрыт для гостей] / JS, правильные серверные часы / 10 сообщений из 10, страница 1 из 1
04.03.2015, 12:48
    #38894483
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JS, правильные серверные часы
Нужно выводить на странице дату и время сервера, обновляемые каждую секунду.
Время от времени (раз в минуту или раз в 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
04.03.2015, 13:13
    #38894513
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JS, правильные серверные часы
В таком виде часы тикают нормально:
Код: 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
04.03.2015, 13:27
    #38894535
kunaksergey
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JS, правильные серверные часы
Alibek B.,
А для чего такой изврат? Один раз возьмите время с сервера, высчитайте разницу между timestamp сервера и у вас.
...
Рейтинг: 0 / 0
04.03.2015, 13:50
    #38894560
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JS, правильные серверные часы
Страница может быть открыта долго, десятки часов, расхождения могут быть заметными.
Кроме того, если пользователь изменит часы на своем ПК, результат будет неадекватным.
Поэтому я бы не хотел ориентироваться на локальный таймстамп.
...
Рейтинг: 0 / 0
04.03.2015, 14:32
    #38894638
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JS, правильные серверные часы
Причину рекурсии вроде бы нашел — если 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
04.03.2015, 15:08
    #38894713
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JS, правильные серверные часы
Кажется нашел, в чем дело.
Асинхронный запрос срабатывает слишком быстро, функция 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
04.03.2015, 15:37
    #38894746
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JS, правильные серверные часы
Вообщем разбил на три функции, теперь все работает нормально.
Код: 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
04.03.2015, 15:59
    #38894770
вадя
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JS, правильные серверные часы
Alibek
задача решается в одно дейстаие с использованием websocket
...
Рейтинг: 0 / 0
04.03.2015, 16:01
    #38894773
Alibek B
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JS, правильные серверные часы
Каким образом?
...
Рейтинг: 0 / 0
04.03.2015, 16:26
    #38894805
kunaksergey
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
JS, правильные серверные часы
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
Форумы / HTML, JavaScript, VBScript, CSS [игнор отключен] [закрыт для гостей] / JS, правильные серверные часы / 10 сообщений из 10, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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