Tuesday, January 3, 2017

Socket.io countdown synchronously?

Leave a Comment

On my server-side script I call two emits at the same time, which looks like this.

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

The one is for the opponent and the other for himself.

My question is when data is loaded a countdown will appear for both players in my android app. For me it's important that they see the same number on their screen and play music at the same time.

I'm open for all tips.

4 Answers

Answers 1

I have made an application and I had the same problem. In That case I solved the problem leaving the time control to the server. The server send to the client and the client increases the time. Maybe in your case you could have problem with connection. If the problem exists you can leave clients to increase time by yourself and some times send a tick with correct time for sync.

Answers 2

I could give you something like bellow but I am not tested. This solution have these steps:

  1. Synchronize timers for client and server. all users have the same difference with server timer.
  2. For the desired response/request get clients time and find the differences with server time.
  3. Consider the smallest as first countdown which will be started.
  4. For each response(socket) subtract the difference from smallest and let the client counter starts after waiting as much as this time.

The client that gets 0 in response data will start immediately. and the main problem that you may will have is broadcast method which you can't use if you think this solution will be helpful. This is a post may will help you.

Answers 3

Add time into emit message. Let's say that songs is an object with
{"time" : timeString, "songs" : songsList}.

If we consider devices time is correct You can calculate the time needed for information to travel and then just use server timer as a main calculator.

The client would get the time when countdown should start:

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 } 

And that works fine when 2 clients are from same time region, therefore You will need "time converter" to check if time is good due to time difference if You strictly need same numbers.

After the countdown has ended You should clearInterval(intervalID);

Answers 4

As far as js timers are concerned the will be a small amount of difference. We can reduce the difference in time with reduce of latency time, with the difference between the request and response time from the server.

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); } 

Elapsed time between sending the request and getting back the response need to be calculated, divide that value by 2. That gives you a rough value of latency. If you add that to the time value from the server, you'll be closer to the true server time (The difference will be in microseconds)

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

Hope this helps.

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment