Синхронизация таймера обратного отсчета

BRat

o_0
ast-ross
не обижайся. споришь ты не по делу. Тебе сказали единственный возможный здесь подход, если не можешь его грамотно реализовать - в топик Работа.
 

ksnk

прохожий
ast-ross
я попробую объяснить о чем говорит BRat

в момент "обновления сессии" запоминается "время обновления". Каждое открытое окно раз в минуту читает это самое "время" и выводит (Now+10минут-время) в нужное юзеру окно. По достижении 0 выполняется запрос на уточнение времени, а не запрос на закрытие сессии. Так как "обновляется" сессия только одним окном, все остальные узнают об этом не позднее чем через минуту (.для определенности.). В течении этого времени в окнах будут некорректные значения. вот это, видимо, и называется "съехал".

Итого: никто из JS не пишет в базу... это не нужно
Используя куки можно все это пережить без особых глюков.
А нафига нам база, если у нас есть сессия? Или сессия - это нечто особое?
 

ast-ross

Новичок
Автор оригинала: ksnk
Так как "обновляется" сессия только одним окном
Что произойдет если пользователь закроет именно это окно? (я называл его ранее мастер-ом). Или все таки обновляет то окно которое запросило данные из сессии раньше? Здесь немного не допонял...
 

HraKK

Мудак
Команда форума
Окно или другое окно запроси _текущее_ время с сервера и все будет пучком.
Так как в ЭТОМ варианте в отличии от ТВОЕГО время хранится не в "окне" а на сервере.
 

ksnk

прохожий
Что произойдет если пользователь закроет именно это окно?
Ну и что? Эталонное время все равно храниться на сервере (в куке). Все остальные ориентируются не по мифическому "мастеру", а по этому эталону...
 

ast-ross

Новичок
Автор оригинала: ksnk
Ну и что? Эталонное время все равно храниться на сервере (в куке). Все остальные ориентируются не по мифическому "мастеру", а по этому эталону...
Все въехал в схему, она не подойдет так как при любом действии (в любом из окон) надо сбрасывать таймер в начало отсчета... Так что не эталонное время нужно а синхронизация...
 

BRat

o_0
веришь, нет - но эталонное время и синхронизация это не взаимоисключащие понятия. Интересно что с чем ты синхронизировать собрался
 

ast-ross

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

-~{}~ 14.03.07 22:37:

BRat, ну не цепляйся к словам ну не все сразу же становятся вменяемыми программерами. Если есть желание помочь - помоги...
 

BRat

o_0
ast-ross
тебе тут помогают начиная с 14:46, уже написали всё что можно было написать.. осталось действительно только код сюда впихнуть

время в куку, куку обновляй на сервере, при запросах со страниц, запрашивай ее JS. Боишься что не будет кук - храни время в БД, файле.

Сколько повторять можно?)

Всё, больше сюда не пишу
 

ast-ross

Новичок
Ладно, кажеться понял идею - осталось реализовать... Действительно все сводиться именно к серверному (эталонному) времени. Спасибо BRat!
 

grigori

( ͡° ͜ʖ ͡°)
Команда форума
уникальный случай - человек осознал правильность чужого подхода
респект, ast-ross
 

ast-ross

Новичок
Сделал без серверного времени и аякса (на аяксе при 10 окнах таймер начинает обновляться не раз в секунду а раз в 5-6 секунд при скорости соединения 30 кб/с)
Вот код (функции setCookie(), getCookie() не мои нашел в тырнете)

Сделано на JS и Cookies:

index.html
Код:
<html>
 <head>
  <title>test</title>
  <script type="text/javascript" src="./main.js"></script>
 </head>
 <body onload="iss_timer('begin', 4210);">
  <p id="iss_timer">00:00:00</p>
  <br><a href="./index.html">new</a><br>
 </body>
</html>
main.js
Код:
function iss_timer(timer_status, timer_left) {
 var current_date = new Date();
 var current_seconds = Math.round(eval(current_date.getTime())/1000);
 if (timer_status == 'begin') {
  setCookie("timer_start", current_seconds, "", "", "", "");
  setCookie("timer_seconds", timer_left, "", "", "", "");
  }
 var timer_start = getCookie("timer_start");
 var timer_seconds = getCookie("timer_seconds");
 var left_seconds = eval(timer_seconds) - (current_seconds - eval(timer_start));
 if (left_seconds < timer_left) {
  var timer_h = Math.floor(left_seconds / (60 * 60));
  var timer_m = Math.floor((left_seconds - (timer_h * 60 * 60)) / 60);
  var timer_s = left_seconds - (timer_h * 60 * 60) - (timer_m * 60);
  if (timer_h < 10) timer_h = '0' + timer_h;
  if (timer_m < 10) timer_m = '0' + timer_m;
  if (timer_s < 10) timer_s = '0' + timer_s;
  document.getElementById('iss_timer').innerHTML = timer_h + ':' + timer_m + ':' + timer_s;
  }
 if (left_seconds > 0) setTimeout("iss_timer('continue', " + left_seconds + ");", 10);
 else alert('TIMEOUT!');
 }
А вот функции для работы с куками:
Код:
function setCookie(name, value, expires, path, domain, secure) {
 document.cookie = name + "=" + escape(value) +
 ((expires) ? "; expires=" + expires : "") +
 ((path) ? "; path=" + path : "") +
 ((domain) ? "; domain=" + domain : "") +
 ((secure) ? "; secure" : "");
 }

function getCookie(name) {
 var cookie = " " + document.cookie;
 var search = " " + name + "=";
 var setStr = null;
 var offset = 0;
 var end = 0;
 if (cookie.length > 0) {
  offset = cookie.indexOf(search);
  if (offset != -1) {
   offset += search.length;
   end = cookie.indexOf(";", offset);
   if (end == -1) {
    end = cookie.length;
	}
   setStr = unescape(cookie.substring(offset, end));
   }
  }
 return(setStr);
 }
Жду ваших комментариев!

-~{}~ 18.03.07 19:55:

Время хоть и не серверное но эталонное клиентское: current_seconds
По-моему погрешность в синхронизации таймера будет составлять не более одной сотой секунды, так как рекурсивный вызов будет происходить каждые 10 миллисекунд: setTimeout("iss_timer('continue', " + left_seconds + ");", 10); Именно по этому был введен лишний параметр timer_left, нужен он только для того что бы не происходил innerHTML каждые 10 миллисекунд а только в случае смены оставшегося времени таймера т.е. 1 раз в секунду. Просто осел при одновременно открытых 10 окнах и при рекурсии в 100 миллисекунд начинает искожать все gif картинки (покрываються вертикальными полосками). Я честно говоря не знаю из-за этого ли, но в любом случае зачем слишком часто переписывать таймер если он все равно не изменился...

-~{}~ 18.03.07 20:03:

Да, время таймера указывается в секундах (2-й параметр) при onload. Может имеет смысл доработать и в готовые решения? Кстати по функциям кук если что заметите не проходите мимо, ткните носом ;)
 

BRat

o_0
а ведь так и не понял что ему писали -)

работать наверно будет.. только куки на сервере устанавливай, а не на клиенте. Тебе же их все равно в ajax-обработчике придется при каждом действии обновлять
 

ksnk

прохожий
Интересно, чем объясняется столь широкое использование функции eval? С точки зрения типов и приводимости одного к другому Javascrpipt еще "гибче", чем PHP так что в этих местах eval просто не нужен, а упоминание о нем на этом форуме может быть еще и вредно для здоровья :)
Я честно говоря не знаю из-за этого ли, но в любом случае зачем слишком часто переписывать таймер если он все равно не изменился...
Это мысли вслух, или вопрос к общественности? :)
 

ast-ross

Новичок
Поясни как на сервере куки устанавливаются, я чесно говоря думал что куки только в браузере на клиенте можно выставить. А зачем мне их через аякс обновлять? Вместо alert('TIMEOUT!'); вызову аякс функцию что то типа x_iss_lock(); (sajax) Да и потом если выствавить куки через PHP разве я их через JS не увижу? И на оборот...

-~{}~ 18.03.07 20:36:

Интересно, чем объясняется столь широкое использование функции eval? С точки зрения типов и приводимости одного к другому Javascrpipt еще "гибче", чем PHP так что в этих местах eval просто не нужен, а упоминание о нем на этом форуме может быть еще и вредно для здоровья :)
Перестраховался, так что лучше вообще убрать его везде?
Это мысли вслух, или вопрос к общественности? :)
Вопрос шепотом :D
 

ksnk

прохожий
Вопрос шепотом
{ немного чуши почислил ;) }
Чтобы не перерисовывать часто часы достаточно их "не перерисовывать" :) например так:
var i=document.getElementById('iss_timer');
if (i.innerHtml != s) i.innerHtml=s;
 

BRat

o_0
чтобы не зависеть от времени клиента и иметь возможность проверять факт таймаута на сервере

$_COOKIE
[m]setcookie[/m]
про ajax вру. у тебя его нет
 

ast-ross

Новичок
Ну, если это все-таки вопрос, то:
Чтобы не писать вот так, придумана функция toPrecision
var s=timer_h.toPrecision(2) + ':' + timer_m.toPrecision(2) + ':' + timer_s.toPrecision(2)
Во я искал как это сделать в инете наткнулся на такой способ как у меня думал в JS такого нет :) Спасибо!

Чтобы не перерисовывать часто часы достаточно их "не перерисовывать" :) например так:
var i=document.getElementById('iss_timer');
if (i.innerHtml != s) i.innerHtml=s;
Думал я об этом и мне показалось что лучше гонять лишнюю переменную по рекурсии, чем дергать getElementById, ну если это не так то подправлю. Только если не сложно поясните чем так лучше...

-~{}~ 18.03.07 21:25:

Автор оригинала: BRat
чтобы не зависеть от времени клиента и иметь возможность проверять факт таймаута на сервере
Ну да на сервере лучше так как клиент может вырубить JS и таймер встанет. Но для этого я перестраховываюсь на сервере проверяя время последнего обновления $_SESSION['timeout'] который выставляеться каждый раз в начале.
Ну так setcookie на клиенте же выставляет кукисы...

про ajax вру. у тебя его нет
Почему sajax разве не ajax-библиотека?
 

BRat

o_0
ох..
кука выставляется _клиенту_ _сервером_ . Серверное время.

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

чем дергать getElementById
оптимизатор блин :)
 

ast-ross

Новичок
А ну да так и есть :) Так что лучше гонять переменную или дергать getElementById?
 
Сверху