Synchronisation JS temps entre plusieurs appareils
Je suis en utilisant le merveilleux reveal.js bibliothèque pour créer un diaporama HTML. Mon seul problème est que j'ai besoin de les synchroniser sur plusieurs appareils.
Pour le moment, je fais une requête AJAX au moment à partir du serveur et de garder une horloge interne pour la page.
function syncTime() {
//Set up our time object, synced by the HTTP DATE header
//Fetch the page over JS to get just the headers
console.log("syncing time")
var r = new XMLHttpRequest();
r.open('HEAD', document.location, false);
r.send(null);
var timestring = r.getResponseHeader("DATE");
systemtime = new Date(timestring); //Set the time to the date sent from the server
}
Bien que cela me met dans 1 secondes de précision, j'ai besoin de faire mieux. La différence est vraiment notable lorsque le diaporama est auto avancer.
Le code va être l'exécution de tous sur la même plate-forme, de sorte que la compatibilité inter-navigateur n'est rien à s'inquiéter.
Voici ce que j'ai réussi à mettre ensemble
Des idées?
Vous devez vous connecter pour publier un commentaire.
Comment sur une approche différente: qui se soucie? (Vous n'allez pas fiable pour la synchronisation de l'horloge système avec JavaScript.)
Au lieu de cela, utilisez un Nœud serveur avec socket.io synchroniser lors de vos clients à l'avance le diaporama. Au lieu de les clients de décider à l'avance, le serveur lui indique.
Cette approche est livré avec l'avantage supplémentaire d'être en mesure manuelle de jouer avec le diaporama en cours d'exécution. Dans l'exemple qui suit, j'ai ajouté un Prochaine bouton qui provoque tous les clients connectés immédiatement passer à la diapositive suivante.
app.js
views/index.html
Ce fichier est traité comme un doT modèle.
Copiez ces deux fichiers dans un dossier, puis exécutez
et accédez à
http://localhost:70
dans plusieurs fenêtres différentes, alors, de voir la magie.sudo node app.js
sudo
vient de l'écoute sur le port de 70, de changer pour quelque chose >1024 à corriger.Mesurer le temps écoulé entre l'envoi de la demande et l'obtention de la réponse. Ensuite, divisez cette valeur par 2. Qui vous donne une valeur approximative de latence. Si vous ajoutez à cela le temps de la valeur à partir du serveur, vous serez au plus proche de la véritable serveur de temps.
Quelque chose comme cela devrait fonctionner:
Intéressant de côté: John Resig a un bon article sur l'exactitude de Javascript calendrier.
Elle ne devrait pas être un problème dans ce cas, puisque vous n'êtes intéressé que par votre temps à être hors de ~1 seconde. 15 ms différence ne devrait pas avoir beaucoup d'effet.
Je suis content que vous avez trouvé une réponse satisfaisante à votre question. J'ai eu une semblable nécessité de synchroniser le navigateur avec le serveur d'horloge, et il était déterminé à parvenir à mieux que 1 seconde précision comme vous étiez. J'ai écrit le code pour faire cela et je suis de poster cette réponse ici au cas où quelqu'un d'autre a besoin de la solution.
Le code est appelé ServerDate et est librement disponible pour le téléchargement. Voici une partie du fichier README. Remarquez que j'ai atteint 108 ms précision dans mon exemple:
Vous pouvez utiliser
ServerDate
comme vous le feriez utiliser leDate
de la fonction ou de l'un de sescas, par exemple:
Il y a aussi une nouvelle méthode pour obtenir la précision de ServerDate estimation de la
l'horloge du serveur (en millisecondes):
Vous pouvez voir la différence entre l'horloge du serveur et les navigateurs de l'horloge, en millisecondes:
Vous ne pouvez pas vraiment synchroniser avec le serveur. En mesurant le temps de votre demande de serveur besoins (comme MikeWyatt suggéré) n'est pas un bon indicateur sur le temps de latence.
Seulement votre serveur sait, lorsqu'il répond à une demande. Par conséquent, il doit la transmettre que les informations de retour avec la réponse. Avec
Date.now() - new Date(timestringOfServerResponse)
vous pouvez mesurer le temps de latence exactement. Pourtant, je ne suis pas sûr pourquoi vous avez besoin de cette valeur.Pour synchroniser une application entre mulitiple appareils, le serveur doit envoyer leur action à effectuer lors de l'. Le "quand" ne doit pas être "dès que vous obtenez ma réponse", mais un horodatage exact. Aussi loin que l'horloge système de votre précision des appareils et synchronisés (ils sont généralement), l'application va s'exécuter ses méthodes synchrounously, parce qu'il sait ce qui se passera quand (ou au moins: ce qui aurait dû se passer ensuite, et il peut interpoler que se "maintenant").
Je suis largement à l'aide de la COMÈTE patron ici pour mon web en temps réel de l'application.
À utiliser que dans votre cas, vous auriez besoin des clients d'ouvrir une requête AJAX vers le serveur et d'attendre une réponse. Dès qu'il arrive, le client doit modifier les diapositives.
Sur le serveur que vous avez à retenir toutes les réponses jusqu'à ce qu'il est temps de changer les lames. (Vous pourriez être plus avancé et le retard par la suite sur le client pour le même temps de chacun, mais c'est probablement pas nécessaire). Je ne peux pas vous montrer un exemple de code pour que ici que je ne sais pas ce qui est disponible pour vous.
Si vous êtes effectivement la création d'un orchestre où le serveur joue le chef d'orchestre et tous les clients sont à l'écoute de lui.
Timing est alors déterminée par la capacité du serveur à répondre à la demande au (presque) le même temps, plus la latence du réseau.
Habituellement, les clients doivent être dans la même partie du réseau afin de latence peut être très semblable, et la valeur absolue n'est pas mal ici, seule la variation.
Et il peut aussi être une astuce supplémentaire aidant: ne pas modifier les diapositives avec un disque de remplacement, les mélanger. Ce sera flou de le modifier, de sorte que l'œil ne peut pas attraper le peu de différences de calendrier que vous aurez toujours sur vous.
(Si vous ne pouvez pas avoir le serveur de jouer le chef d'orchestre, vous êtes susceptible d'avoir à utiliser la solution par MikeWyatt - sans doute avec un peu de demandes, et en arrondissant le résultat, en fonction de la configuration du réseau. Dans un réseau local, une demande peut être suffisant, allez sur l'ensemble de l'internet un peu plus de la moyenne ne fera pas de mal...)