2013-03-05 15 views
7

Ich habe zwei JavaScript-Countdown-Timer (für ein Spiel) und eine MySQL-Tabelle, um Daten von AJAX-Anrufe von beiden zu erhalten.Synchronisieren Sie zwei clientseitige JavaScript-Timer mit Server

Das Verfahren ist folgendes:

  1. ein Client startet den Timer, schreibt es data1 MySQL Spalte, so dass den Timer und eine time1 Spalte mit dem aktuellen Zeitstempel (mit .01s Präzision gestartet von der PHP Aufruf als MySQL nicht tun)

  2. den anderen Client (Polling des Servers im 2s-Wechsel) erkennt die Änderung und startet einen Timer, aber sofort subtrahiert (es ist ein Countdown-Timer) ctime - time1 Dabei ist ctime der Zeitstempel vom zweiten Client-Aufruf (ebenfalls vom PHP gegeben) und time1 ist der Zeitstempel, den der erste Client geschrieben hat, als er den Timer gestartet hat.

Dieses Verfahren sollte durch die 2s Intervalle der Abfrage der Verzögerung verursacht werden, aber unabhängig davon, ob es funktioniert oder nicht (ich bin nicht wirklich sicher, um ehrlich zu sein), variiert die Sync zwischen den Timern . Manchmal sind sie tot genau, manchmal sind sie um bis zu 3 Sekunden ausgeschaltet. (Es ist unzuverlässig.)

Hier einige meiner entsprechenden Code ist Ich verwende:

var timerRunning, timeRemaining, responseTime; 

function restartLocalTimer() { 
    var d = new Date(); 
    responseTime = d.getTime()/1000; 
    timerRunning = true; 
    timerTick(); 
} 

function restartSyncTimer(resp) { // resp is the AJAX response passed 
    var d = new Date(); 
    responseTime = d.getTime()/1000 - parseFloat(resp["ctime"]) + parseFloat(resp["time"]); 
    timerRunning = true; 
    timerTick(); 
} 

function timerTick() { 
    d = new Date(); 
    timeRemaining = 20 - d.getTime()/1000 + responseTime; 
    if (timerRunning) setTimeout("timerTick()",25); 
} 

Alle Zeitwerte in Sekunden sind. (Wegen der Datenbank, könnte sich zu ms später ändern.)

Meine Fragen sind: Gibt es zusätzliche (signifikante) Verzögerungen, die ich nicht verrechne? Gibt es einen besseren Weg, dies zu tun?

Beachten Sie auch: Ich bin offen für jQuery (es bereits für die AJAX-Aufrufe verwenden), aber keine Web-Sockets verwenden möchten.

+1

Ok, also habe ich es diesmal gelesen. Zuallererst: Warum benutze 'setTimeout (" timerTick() ", 25)'? Warum nicht 'setTimeout (timerTick, 25)'. Das erste Argument von 'setTimeout' nimmt eine Funktionskennung. Zweitens: Was passiert, wenn Sie zum Beispiel die Timeline- oder Netzwerkseite von Google Chrome in der Konsole verwenden? Ist das hilfreich, um zu erkennen, was die Verzögerung verursacht, oder haben Sie das bereits versucht? –

+0

okay, die erste Sache ist ziemlich nur Ästhetik, aber trotzdem danke. Was die Timeline anbetrifft, werde ich mehr darauf eingehen. –

+0

'resp [" time "]' ist der Zeitstempel, zu dem Sie zählen? – Bergi

Antwort

1

Ich würde den gleichen Ansatz, den Desktop-Netzwerk-Multiplayer-Spiele nehmen. Selbst während kurzer Momente der Verbindungsunterbrechung (z. B. "Verzögerung") projiziert der Client die erwarteten Trajektorien während dieser Zeit. In diesem Fall verlassen Sie sich auf ein lokales Intervall und aktualisieren mit der genauen Serverzeit, wenn Sie die asynchrone Heartbeat-Antwort erhalten.

-1

setTimeout und seine Brüder sind dafür bekannt, unzuverlässig zu sein. Es gibt einen weiteren Beitrag dazu: Is there a more accurate way to create a Javascript timer than setTimeout?, der einige Hinweise gibt.

+0

herunterzählen bemerke, dass setTimeout nur die Funktion in regelmäßigen Abständen ausführt, aber keine Zeit releated Berechnungen. Das geschieht über Datum –

+2

Es ist, weil ich glaube nicht, dass Sie meinen Code gelesen haben, sah nur die setTimeout() und machte sofort Annahmen. So postest du keine Antwort. Ein Kommentar, vielleicht. –

+0

Sie haben Recht, reagierte zu schnell. Hab mich letzte Woche verknallt, also habe ich zu schnell gefolgert, das war genauso. –

Verwandte Themen