Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/41.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何减少客户端在socket.io中接收数据的时间差?_Javascript_Node.js_Express_Websocket_Socket.io - Fatal编程技术网

Javascript 如何减少客户端在socket.io中接收数据的时间差?

Javascript 如何减少客户端在socket.io中接收数据的时间差?,javascript,node.js,express,websocket,socket.io,Javascript,Node.js,Express,Websocket,Socket.io,包含模块socket.io和express的node.js项目 现在,每个客户端都有一个画布,可以在上面运行动画。当服务器发出initiate参数时,动画可以开始 现在的问题是,当客户端的动画开始时,它们之间存在时间间隔。动画运行的时间越长,差距就越明显。数字的位置将变得完全不同。但我想要的是每个人都能在屏幕上看到同样的东西 以下是服务器传递数据的方式: socket.broadcast.emit('init', initData); socket.emit('init', init

包含模块socket.io和express的node.js项目

现在,每个客户端都有一个画布,可以在上面运行动画。当服务器发出initiate参数时,动画可以开始

现在的问题是,当客户端的动画开始时,它们之间存在时间间隔。动画运行的时间越长,差距就越明显。数字的位置将变得完全不同。但我想要的是每个人都能在屏幕上看到同样的东西

以下是服务器传递数据的方式:

   socket.broadcast.emit('init', initData);
   socket.emit('init', initData);
动画功能位于客户机中,它在从服务器接收启动数据时启动

我不确定这是否是因为每个客户端接收这些数据的时间不同

那么如何缩小这一差距呢


非常感谢。

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

这里有一个简单的公式和例程,可用于socket.io、php或其他任何真正的工具。 在直播前10秒,我用它淡入了一个视频流。考虑到固有的滞后和设备性能模式,以及错误的时区,您只能期望向前或向后获得30毫秒左右的精度,但对于大多数观察者来说,这一切都是“同时发生的”

这是一个服务器的模拟,它比模拟客户端(您)落后大约两分钟,服务器希望客户端在1.2秒内显示一个弹出窗口:

//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);
这有多可靠?尝试将“-123456”s和“+12345”s更改为“+12345”,查看弹出窗口是否仍等待1.2秒才能触发,尽管计算中没有使用Math.abs

在socket.io中,您可以将服务器时间和计划时间发送到客户端,以便在预事件中进行计算:

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

然后使用这些值和上面的数学公式,根据需要将动画安排在几分钟或几小时内,按需(您的)到分秒。

您需要推算航位技术,以便在服务器上模拟尽可能接近真实状态的客户端状态。
您可以定期向客户端发送状态包,例如每200ms(每秒5次),并在客户端根据此数据进行推断

除此之外,您还必须记住不同客户机的不同延迟。因此,当您想要保持相同的状态时,通常有两种方法-插值(使用最后一种已知方法和数据之前的一种方法)或外推(使用最后一种已知方法并根据自己的延迟预测未来)。
外推更适合于实时交互内容,但在错误纠正方面会有问题-当客户端进行错误预测时(对象突然停止,但基于客户端预测的延迟,它仍然移动)。

插值将使一切都变得相当延迟,成为过去,但不会出现错误,因为没有预测。这样做的缺点是,您需要等待,然后再插入与最慢延迟用户相等的时间量。这意味着速度较慢的用户也会强制所有人减速。

不要在数据传递事件上启动动画,发送数据和服务器时间戳,以及何时启动动画的时间戳。在客户端上,为(开始时间戳-(服务器时间-客户端时间))设置一个超时,通过从动画数据中清除数据通道并防止延迟影响开始时间,它应该在每个客户端上同时播放。@dandavis,客户端将读取其系统时间,这可能会导致更大的时间间隔。我遗漏了等式中的一个项,这假设服务器打印和连接关闭之间的间隔可以忽略不计,这是典型的,因为大多数行程时间都是提前的。我需要一个答案来解释。。。