Socket.io 在服务器端丢失数据

Socket.io loses data on server side

黄色,

所以,我正在节点上制作一个多人在线游戏(为了好玩),我被一个问题困了一个多星期了。也许解决方案很简单,但我忘记了。 长话短说:

  1. 数据从客户端发送到服务器,这 emit 每隔 16.66 毫秒。
  2. 服务器正确接收它们,我们收集所有数据(大量 在这种情况下是火球)。我们将它们保存在 player.skills_to_execute 数组。
  3. 每 5 秒,我们将数据复制到单独的数组 (player_information),因为 我们要清理当前的那个,这样它就可以继续收集新的 数据,然后我们将所有收集到的数据发送回客户端。

问题肯定出在服务器端。 有时这行得通,有时行不通。 player_information 是我发送回前面的数组,但在我发送它之前,我会检查服务器上的 console.log 是否确实包含数据, 并且确实如此!但是不知何故,数据在发送之前就得到了 deleted/overwritten 并且它发送了空数组(因为我检查了前端并且我收到了空数组)。

代码相当复杂,但我在这里将其最小化,以便更容易理解。

此代码保留在客户端,并按预期工作:

// front.js
socket.on("update-player-information", function(player_data_from_server){
   console.log( player_data_from_server.skills_to_execute );
});

socket.emit("update-player-information", {
    skills_to_execute: "fireball"
});

此代码保留在服务器端,并按预期工作:

// server.js    
socket.on("update-player-information", function(data){

   // only update if there are actually skills received
   // we dont want every request here to overwrite actual array with empty []                     // data.skills_to_execute = this will usually be 1 to few skills that are in need to be executed on a single client cycle
   // naturally, we receive multiple requests in these 5 seconds, 
   // so we save them all in player object, where it has an array for this

   if ( data.skills_to_execute.length > 0 ) {
      player.skills_to_execute.push( data.skills_to_execute );    
   }

});

现在是代码,该代码很糟糕。

// server.js
// Update player information
setInterval(function(){
   // for every cycle, reset the bulk data that we are gona send, just to be safe
   var player_information = [];

   // collect the data from player
   player_information.push(
      { 
         skills_to_execute: player.skills_to_execute
      }
   );

   // we reset the collected actions here, cause they are now gona be sent to front.js
   // and we want to keep collecting new skills_to_execute that come in
   player.skills_to_execute = [];

   socket.emit("update-player-information", player_information);

}, 5000);

也许有人有什么想法?

按值而不是按引用复制数组。

试试这个:

player_information.push(
  { 
     skills_to_execute: player.skills_to_execute.slice()
  }
);

阅读更多关于在 JavaScript 中按值或按引用复制数组的信息:Copying array by value in JavaScript