side que node javascript serverside-javascript

que - Cómo sincronizar una cuenta atrás de javascript con la hora del servidor



node.js server-side javascript virus (4)

Estoy construyendo un sitio que tiene tiempos y precios que marcan hacia abajo. Lo que más me preocupa es el tiempo de sincronización para que sea lo más preciso posible para todos los clientes.

Actualmente, le estoy enviando al cliente la cantidad de milisegundos restantes que luego se usa para alimentar el temporizador de cuenta regresiva, pero debido a retrasos en la transferencia y la representación, esto puede apagarse por varios segundos, incluso con 2 navegadores en la misma computadora.

¿Hay alguna manera de sincronizar la hora de javascript y la hora del servidor del cliente, o simplemente tendré que lidiar con este ligero retraso?

Si solo hubiera una manera de medir con precisión la diferencia de tiempo entre el servidor que envía los datos y que el cliente los recibe y los procesa.


A pesar de que el tiempo en el servidor y el cliente será diferente, la velocidad a la que los cambios de tiempo deberían ser esencialmente iguales. Enviaría el tiempo restante al cliente, permitiría que el cliente agregue ese tiempo a la hora actual y luego haga que el cliente calcule la cuenta regresiva a partir de eso. Por ejemplo:

var timeRemaining = [rendered on page load or queried by ajax]; // in milliseconds var endTime = new Date(new Date().getTime() + timeRemaining); // Put this in a setInterval, or however you currently handle it var countdown = (endTime.getTime() - new Date().getTime()) / 1000;


Hay una manera de sincronizar un cliente con la hora del servidor. Escribí una biblioteca que hace esto: ServerDate .

Aquí está parte de la README:

Puede usar ServerDate como usaría la función Date o una de sus instancias, por ejemplo:

> ServerDate() "Mon Aug 13 2012 20:26:34 GMT-0300 (ART)" > ServerDate.now() 1344900478753 > ServerDate.getMilliseconds() 22

También hay un nuevo método para obtener la precisión de la estimación de ServerDate del reloj del servidor (en milisegundos):

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

Puede ver la diferencia entre el reloj del servidor y el reloj del navegador, en milisegundos:

> ServerDate - new Date() 39


La solución a esto es Javascript: puede acceder a la configuración de zona horaria en el cliente. Desafortunadamente, solo puede obtener sus compensaciones de zona horaria (especificadas en minutos) para fechas específicas, sin nombre de zona horaria. Por lo tanto, para determinar la zona horaria correcta, también necesitamos saber si se está empleando el horario de verano (DST), esta es la parte del cliente de la solución:

var now = new Date(); var later = new Date(); // Set time for how long the cookie should be saved later.setTime(now.getTime() + 365 * 24 * 60 * 60 * 1000); // Set cookie for the time zone offset in minutes setCookie("time_zone_offset", now.getTimezoneOffset(), later, "/"); // Create two new dates var d1 = new Date(); var d2 = new Date(); // Date one is set to January 1st of this year // Guaranteed not to be in DST for northern hemisphere, // and guaranteed to be in DST for southern hemisphere // (If DST exists on client PC) d1.setDate(1); d1.setMonth(1); // Date two is set to July 1st of this year // Guaranteed to be in DST for northern hemisphere, // and guaranteed not to be in DST for southern hemisphere // (If DST exists on client PC) d2.setDate(1); d2.setMonth(7); // If time zone offsets match, no DST exists for this time zone if(parseInt(d1.getTimezoneOffset())==parseInt(d2.getTimezoneOffset())) { setCookie("time_zone_dst", "0", later, "/"); } // DST exists for this time zone – check if it is currently active else { // Find out if we are on northern or southern hemisphere // Hemisphere is positive for northern, and negative for southern var hemisphere = parseInt(d1.getTimezoneOffset())-parseInt(d2.getTimezoneOffset()); // Current date is still before or after DST, not containing DST if((hemisphere>0 && parseInt(d1.getTimezoneOffset())==parseInt(now.getTimezoneOffset())) || (hemisphere<0 && parseInt(d2.getTimezoneOffset())==parseInt(now.getTimezoneOffset()))) { setCookie("time_zone_dst", "0", later, "/"); } // DST is active right now with the current date else { setCookie("time_zone_dst", "1", later, "/"); } }

Guarda los resultados como cookies, a las que puede acceder desde su script PHP. Debe incluir el código anterior en al menos la primera página a la que accede un usuario. Lo incluyo en cada página para reconocer (y adaptarse a) los cambios, incluso si dichos cambios durante una sesión son poco probables.

En PHP, puede extraer una zona horaria válida con una nueva función llamada timezone_name_from_abbr, disponible desde PHP 5.1.3. Puede usar una abreviatura de zona horaria o una combinación de desplazamiento de zona horaria (en segundos) y horario de verano. última combinación:

$time_zone_name = timezone_name_from_abbr(", -$_COOKIE[''time_zone_offset'']*60, $_COOKIE[''time_zone_dst'']);

Esto le dará un nombre de zona horaria correcto para el usuario, si los datos de las cookies son válidos. Tenga en cuenta que hay muchos nombres "duplicados", por ejemplo, "Europa / Berlín" y "Europa / Zúrich", que tienen la exacta configuración de la misma zona horaria (al menos por ahora), y puede obtener una de ellas para el desplazamiento apropiado y las variables DST. La lista de nombres de zonas horarias se puede encontrar en la Lista de zonas horarias admitidas en php.net.

Creación de cadenas de fecha con una zona horaria determinada Con el nombre de la zona horaria del usuario, ahora puede usar las clases PHP DateTimeZone y DateTime para finalmente crear cadenas de fecha con la zona horaria correcta:

// Create time zone class $time_zone_class = new DateTimeZone($time_zone_name); // Create new date class with a given date // Notice that the provided date will be regarded as being in the // default time zone and converted accordingly $new_date = new DateTime(‘2007-02-14 15:30:00′, $time_zone_class); // Print date with the user’s time zone echo $new_date->format(‘Y-m-d H:i:s’);

¡Eso es!

Fuente: http://togl.me/eE2


Puede medir el tiempo que tarda todo el viaje de ida y vuelta del servidor y dividirlo entre dos para obtener una buena estimación de la diferencia horaria. Tenga cuidado: no se garantiza que los paquetes IP tomen la misma ruta en ambas direcciones, pero la posibilidad de hacerlo es bastante alta.

Puede usar Date.getTime() si la resolución de milisesonds es suficiente para usted.