简体   繁体   中英

How to reduce time difference between clients receiving data in socket.io?

A node.js project with modules socket.io and express.

Now each client has a canvas, which runs animations on it. When server emit the initiate parameter, the animation can start.

Now the problem is, there is a Time Gap between clients when their animations start. The longer the animation runs, the more obvious the gap would be. The position of the figures would become really different. But what i want is everybody see the same thing on their screen。

Here's how the server deliver the data:

   socket.broadcast.emit('init', initData);
   socket.emit('init', initData);

The animation function is in the client, it starts when receiving the initiate data from the server.

I'm not sure if it's because the time receiving these data is different in each client.

So how to reduce this gap?

Many thanks.

我认为您应该尝试以下操作:确保(使用onLoad事件并通过socket.io在服务器上收集该事件)每个客户端都下载了动画,然后发送信号以启动动画。

here is a simple formula and routine that works with socket.io, php or anything really. I used it to fade in a live video stream 10 seconds before it aired. Given the inherent lag and device performance patterns, and wrong time-zones, you can only expect to get about 30ms of precision forward or backward, but to most observers, it all happens "at the same time".

here is a simulation of a server that's about two minutes behind a simulated client (you), and the server wants the client to show a popup in 1.2 seconds:

//the first two vars should come from the server:
var serverWant=+new Date() - 123456 + 1200; // what server time is the event ?
var serverTime=+new Date() - 123456; // what server  time is now ?


//the rest happens in your normal event using available info:
var clientTime=+new Date();       // what client time is now ?
var off= clientTime - serverTime; // how far off is the client from the server?
var clientWant= serverWant + off; // what client time is the event ?
var waitFor = clientWant -  +new Date(); // how many millis to time out for until event ?

setTimeout(function(){ alert( 'SNAP!' );}, waitFor);

how reliable is this? try changing both "- 123456"s to "+ 12345"s and see if the popup still waits 1.2 seconds to fire, despite not using Math.abs anywhere in the calculation...

in socket.io, you could send the server time and scheduled time to the client for computation in a pre-event:

 socket.broadcast.emit('pre-init', { 
     serverTime: +new Date(), 
     serverWant: +new Date() + 1200  
  });

and then use those values and the above math to schedule the animation in a few moments or a few hours as needed, on-demand (yours) to the split second.

You need Dead Reckoning technique in order to simulate client side state as close to real state on server as possible.
You might send state packages to clients periodically, for example every 200ms (5 times a second), and on client side extrapolate from this data.

Additionally to this, you have to remember about different latency for different clients. So as you want to keep same state there is generally two approaches - interpolation (use last known and one before data), or extrapolation (use last known and predict in future based on own latency).
Extrapolation suits better for real-time interactive stuff, but will have problems with error correction - when client will do wrong prediction (object suddenly stopped but based on delay client predicted it still moved).
Interpolation would make everything pretty much delayed and in a past, but will not suffer from errors as there is no predictions. The drawback of this as you need to wait before interpolating amount of time equal to slowest latency user. This means that slower user will force everyone to be slowed down as well.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM