Node.js 如何在带有套接字(socket.io)的NodeJS中找到客户端的响应时间(延迟)?

Node.js 如何在带有套接字(socket.io)的NodeJS中找到客户端的响应时间(延迟)?,node.js,websocket,socket.io,latency,Node.js,Websocket,Socket.io,Latency,我正在尝试用NodeJS创建一个多人游戏,我想在客户端之间同步操作 找到客户机和服务器之间的延迟(请求返回客户机所需的时间)的最佳方法是什么 我的第一个想法是,客户机1可以发送带有is请求的时间戳,因此当客户机2接收到客户机1的操作时,他将调整is操作速度以消除请求的延迟。 但问题是,可能两个客户端的系统日期时间不相同,因此两个客户端不可能根据客户端1的请求知道卷盘延迟 另一个解决方案是使用服务器的时间戳,但是现在我怎么知道客户端的延迟呢?我假设您正在使用WebSocket,或者因为您正在实现一

我正在尝试用NodeJS创建一个多人游戏,我想在客户端之间同步操作

找到客户机和服务器之间的延迟(请求返回客户机所需的时间)的最佳方法是什么

我的第一个想法是,客户机1可以发送带有is请求的时间戳,因此当客户机2接收到客户机1的操作时,他将调整is操作速度以消除请求的延迟。 但问题是,可能两个客户端的系统日期时间不相同,因此两个客户端不可能根据客户端1的请求知道卷盘延迟


另一个解决方案是使用服务器的时间戳,但是现在我怎么知道客户端的延迟呢?

我假设您正在使用WebSocket,或者因为您正在实现一个延迟很重要的游戏(并且您将其标记为延迟)

我认为服务器应该测量并跟踪每个客户机的情况

您可能希望实现某种ping操作,服务器可以请求客户端执行这些操作。客户机一收到请求,就向服务器发回响应。然后,服务器除以2并更新该客户端的延迟。您可能希望服务器定期对每个客户机执行此操作,并可能对最后几个客户机进行平均,这样您就不会因为突然但暂时的峰值而出现奇怪的行为

然后,当一个客户端的消息需要发送(或广播)到另一个客户端时,服务器可以将client1的延迟添加到client2的延迟,并将此作为延迟偏移量作为消息的一部分传递给client2。然后client2就会知道client1上的事件发生在几毫秒前


在服务器上执行此操作的另一个原因是某些浏览器Javascript时间戳不准确:。我怀疑node.js时间戳与V8(为数不多的几个精确的时间戳之一)一样精确(或更精确)。

我通常在请求时发送时间戳:

  • 在客户端上,创建一个
    newdate()
    ,并将
    时间戳:Date.getTime()
    与每个JSON请求一起发送到服务器
  • 在服务器上,在接收到请求后,在对象中放置一个
    processed:(new Date()).getTime()
  • 处理请求
  • 在响应上,放置请求中的
    时间戳
    ,以及一个新的已处理字段:
    processed:(new Date()).getTime()-req.processed
    ,该字段现在包含处理请求所用的毫秒数
  • 在客户端上,当接收到响应时,获取
    时间戳
    (与在pt 1上发送的时间相同)并将其从当前时间中减去,然后减去处理时间(
    已处理
    ),即存在以毫秒为单位的“实时”ping时间

  • 我认为您应该始终在ping时间中包含请求和响应的时间,即使存在单向通信。这是因为这是“ping时间”和“延迟”背后的标准含义。如果是单向通信,延迟只有实际ping时间的一半,这是一件“好事”。

    这是我测试ping的快速而肮脏的脚本。。。只需在浏览器中打开并观看控制台(我的ssh终端)

    var http=require('http');
    var io=require('socket.io');
    server=http.createServer(函数(req,res){
    res.writeHead(200,{'Content-Type':'text/html'});
    res.write('\n');
    res.write('\n');
    res.write('Node Ping\n');
    res.write('\n');
    res.write('\n');
    res.write('var socket=new io.socket();\n');
    res.write('socket.on(“connect”,function(){});\n');
    res.write('socket.on(“message”,function(){socket.send(1);});\n');
    res.write('socket.connect();\n');
    res.write('\n');
    res.write('\n');
    res.write('\n');
    res.write('Node Ping\n');
    res.write('\n');
    res.write('\n');
    res.end();
    });
    监听服务器(8080);
    console.log('服务器在运行http://127.0.0.1:8080/');
    var socket=io.listen(服务器);
    socket.on('connection',函数(客户端){
    var start=new Date().getTime();
    客户端发送(1);
    client.on('message',函数(message){client.send(1);console.log(新日期$
    on('disconnect',function(){});
    });
    
    我对此很好奇,因为在加州和新泽西州都有专用资源的大型vps箱上,我的ping似乎很高(往返200-400ms)。(我在东海岸)我打赌vps箱b/c上有很多延迟,他们提供的流量这么多

    让我感到困惑的是,从linux终端从同一个客户端到同一个服务器的常规ping平均为11毫秒,比原来低了10倍……我是不是在node.js/socket.io/websockets上做错了什么,还是速度太慢了?

    概述: 在socket.io连接建立之后,您在客户端上创建一个新的
    Date
    对象,我们称之为
    startTime
    。这是您向服务器发出请求之前的初始时间。然后您从客户端发出
    ping
    事件。命名约定完全由您决定。同时,服务器应该正在侦听
    ping
    事件,当它接收到
    ping
    时,它立即发出
    pong
    事件。然后客户端捕获
    pong
    事件。此时,您希望创建另一个表示
    date.now()的日期对象
    。因此,此时您有两个日期对象—向服务器发出请求之前的初始日期,以及向服务器发出请求并得到响应之后的另一个日期对象。从当前时间中减去
    startTime
    ,您就得到了
    latency

    客户 服务器
    也可作为。

    先读-提供,原因是反复询问为什么要这样做
    var http = require('http');
    var io = require('socket.io');
    
    server = http.createServer(function (req, res) {
      res.writeHead(200, {'Content-Type': 'text/html'});
      res.write('<html>\n');
      res.write('  <head>\n');
      res.write('    <title>Node Ping</title>\n');
      res.write('    <script src="/socket.io/socket.io.js"></script>\n');
      res.write('    <script>\n');
      res.write('        var socket = new io.Socket();\n');
      res.write('        socket.on("connect",function(){ });\n');
      res.write('        socket.on("message",function(){ socket.send(1); });\n');
      res.write('        socket.connect();\n');
      res.write('    </script>\n');
      res.write('  </head>\n');
      res.write('  <body>\n');
      res.write('    <h1>Node Ping</h1>\n');
      res.write('  </body>\n');
      res.write('</html>\n');
      res.end();
    });
    server.listen(8080);
    
    console.log('Server running at http://127.0.0.1:8080/');
    
    var socket = io.listen(server);
    
    socket.on('connection',function(client){
      var start = new Date().getTime();
      client.send(1);
      client.on('message',function(message){ client.send(1);  console.log( new Date$
      client.on('disconnect',function(){});
    });
    
    var socket = io.connect('http://localhost');
    var startTime;
    
    setInterval(function() {
      startTime = Date.now();
      socket.emit('ping');
    }, 2000);
    
    socket.on('pong', function() {
      latency = Date.now() - startTime;
      console.log(latency);
    });
    
    io.sockets.on('connection', function (socket) {
      socket.on('ping', function() {
        socket.emit('pong');
      });
    });
    
    var start = Date.now();
    this.socket.emit( 'ping', function clientCallback() {
        console.log( 'Websocket RTT: ' + (Date.now() - start) + ' ms' );
    } );
    
    socket.on( 'ping', function ( fn ) {
        fn(); // Simply execute the callback on the client
    } );
    
    npm install
    node callback.js
    
    // (Connect to socket).
    
    var latency = 0;
    
    socket.on('pong', function(ms) {
        latency = ms;
    
        console.log(latency);
    });
    
    // Do cool things, knowing the latency...
    
    var server = require('http').Server(app);
    
    // "socket.io": "^1.7.1"
    // Set pingInterval to whatever you want - 'pong' gets emitted for you!
    var io = require('socket.io')(server, {pingInterval: 5000});