2016-12-25 35 views
7

Na moim skrypcie po stronie serwera wywołuję dwa emity w tym samym czasie, co wygląda tak.Odliczanie Socket.io synchronicznie?

if (songs.length > 0) { 
    socket.emit('data loaded', songs); 
    socket.broadcast.to(opponent).emit('data loaded', songs); 
} 

Ten jest dla przeciwnika, a drugi dla niego samego.

Moje pytanie jest po załadowaniu danych odliczanie pojawi się dla obu graczy w mojej aplikacji na Androida. Dla mnie ważne jest, aby widziały ten sam numer na ekranie i odtwarzać muzykę w tym samym czasie.

Jestem otwarty na wszystkie wskazówki.

+0

Być może klient wysyła z powrotem token oznaczający miejsce, w którym się znajduje, i wysyła tylko wiadomość, aby odliczać, gdy mają tę samą wartość? Myślę, że może to być jedyny sposób, niestety, jeśli wziąć pod uwagę opóźnienie każdego użytkownika. –

+0

@SamJudge możesz wyjaśnić więcej za pomocą przykładów kodu? – enucar

+0

Jak precyzyjnie musisz być? Jak daleko od siebie znajdują się użytkownicy i jakie są opóźnienia między użytkownikami a serwerem? Z powyższym kodem, obaj użytkownicy powinni być blisko synchronizacji, ale to naprawdę zależy od definicji "zsynchronizowanej" ... – jcaron

Odpowiedz

0

Złożyłem wniosek i miałem ten sam problem. W tym przypadku rozwiązałem problem pozostawiając kontrolę czasu na serwerze. Serwer wysyła do klienta, a klient zwiększa czas. Może w twoim przypadku mógłbyś mieć problem z połączeniem. Jeśli problem istnieje, możesz zostawić klientom czas na samodzielne przedłużenie czasu, a czasami wyślij potwierdzenie z właściwym czasem do zsynchronizowania.

0

Mogę ci dać coś jak poniżej, ale nie jestem poddany próbie. To rozwiązanie ma następujące etapy:

  1. liczniki synchronizowanie client i dla server. wszyscy użytkownicy mają ten sam difference z timerem serwera.
  2. Dla żądanego response/request pobierz czas klienta i znajdź differences z czasem serwera.
  3. Rozważ smallest jako pierwsze odliczanie, które zostanie uruchomione.
  4. Dla każdego response(socket)odjąćdifference z smallest i niech klient uruchamia licznik po odczekaniu aż ten time.

Klient, który otrzyma 0 w danych odpowiedzi, rozpocznie się natychmiast. i głównym problemem, który może ci się przydać, jest metoda broadcast, której nie możesz użyć, jeśli uważasz, że to rozwiązanie będzie pomocne. This is a post may will help you.

0

Dodaj czas na emisję wiadomości. Powiedzmy, że utwory to obiekt z
{"time" : timeString, "songs" : songsList}.

Jeśli uznamy, że czas urządzenia jest prawidłowy Możesz obliczyć czas potrzebny na podróż do informacji, a następnie użyj timera serwera jako głównego kalkulatora.

Klient dostanie czas podczas odliczania powinien rozpocząć się:

var start = false; 
var startTime = 0; 
var myTime = new Date().getMilliseconds(); 
var delay = 1000 - myTime; 

setTimeout(function(){ 
    intervalID = setInterval(function(){ 
     myTime = new Date().getTime(); 
     //console.log(myTime); to check if there is round number of milliseconds 
     if (startTime <= myTime && start = true) {startCountdown();} 
    }, 100); //put 1000 to check every second if second is round 
      //or put 100 or 200 is second is not round 
}, delay); 

socket.on('data loaded', data){   
    startTime = data.time; 
    start = true; 
} 

function startCountdown(){ 
    //your time countdown 
} 

i że działa dobrze, gdy 2 klienci są z tego samego regionu czasu, więc trzeba „przetwornik czas”, aby sprawdzić, czy czas jest dobry ze względu do różnicy czasu, jeśli Ty potrzebujesz ściśle tych samych liczb.

Po zakończeniu odliczania Należy clearInterval(intervalID);

1

miarę js czasomierze są zainteresowane będzie niewielka kwota różnicy.Możemy zmniejszyć różnicę w czasie, zmniejszając czas oczekiwania, z różnicą między czasem żądania i czasem odpowiedzi z serwera.

function syncTime() { 
console.log("syncing time") 
var currentTime = (new Date).getTime(); 

res.open('HEAD', document.location, false); 
res.onreadystatechange = function() 
{ 
    var latency = (new Date).getTime() - currentTime; 
    var timestring = res.getResponseHeader("DATE"); 
    systemtime = new Date(timestring); 
    systemtime.setMilliseconds(systemtime.getMilliseconds() + (latency/2)) 
}; 
res.send(null); 
} 

Upływający czas między wysłaniem żądania a wracając odpowiedź musi być obliczony, należy podzielić tę wartość przez 2. To daje przybliżone wartości latencji. Jeśli dodać, że do wartości czasu z serwera, będziesz bliżej do prawdziwego czasu serwera (Różnica będzie w mikrosekund)

referencyjny:http://ejohn.org/blog/accuracy-of-javascript-time/

Nadzieja to pomaga.