javascript - Socket.io 从 Node 中的多个套接字接收数据

标签 javascript node.js sockets npm socket.io

几天前我开始使用 Node 进行开发。我目前正在开发一款使用 Node 作为服务器端应用程序的在线游戏。该应用程序只是向客户端提供 .html 和 .js 文件并处理游戏逻辑。 我正在使用 Socket.io 与客户端交换数据。当新客户端通过 Socket.io 连接到服务器时,程序会查找一个有空闲空间的房间(包含两个用户的套接字和处理逻辑的游戏对象的对象数组)并放置用户(注册套接字)在其中。 我已经能够正确地将 Sprite 的位置发送到每个客户端,但是从每个套接字检索数据时遇到问题:如果我尝试从客户端向服务器发送一些数据,则该数据仅流经其中之一两个套接字,无论哪个客户端发送该套接字。

初始化房间数组

for(var i = 0; i < roomsNumber; i++) {
  //player1 and player 2 are going to store the sockets
  rooms[i] = { player1 : null, player2 : null, game: null};
}

Socket.io 处理连接

var io = require('socket.io')(server);

io.on('connection', function(socket){
  console.log("We have a new client: " + socket.id);
  insertPlayer(socket);

  socket.on('disconnect', function() {
    console.log("Client has disconnected: " + socket.id);
    removePlayer(socket);
  });
});

将客户端添加到房间

function insertPlayer(socket) { //Check for an empty spot in a room
  for(var i = 0; i < rooms.length; i++) {
    if(!rooms[i].player1) {
      rooms[i].player1 = socket; //Register the socket to the room
      checkRooms();
      return;
    }
    if(!rooms[i].player2) {
      rooms[i].player2 = socket; //Register the socket to the room
      checkRooms();
      return;
    }
  }
}

当房间已满时创建游戏对象(并在玩家离开时销毁它)

function checkRooms() { //Checks if a room is full to initialize the game
  for(var i = 0; i < rooms.length; i++) {
    if(rooms[i].player1 && rooms[i].player2 && !rooms[i].game) {
      rooms[i].game = new Game([rooms[i].player1, rooms[i].player2]); //The constructor passes the sockets
      console.log('New game started');
    }
    if((!rooms[i].player1 || !rooms[i].player2) && rooms[i].game) {
      rooms[i].game.endGame();
      rooms[i].game = null;
      console.log('Game stopped');
    }
  }
}

在Game类中接收数据

constructor(sockets) {
  this.sockets = sockets;
  this.snakes = [];
  var self = this;

  for(var i = 0; i < this.sockets.length; i++) {
    this.snakes[i] = new Snake(i*100 + 100, 200);
    var currentSnake = this.snakes[i];
    var currentSocket = this.sockets[i];

  currentSocket.on('keyPressed', function(data) {
    currentSnake.updateDirection(data); //Calls a Game method that updates the direction of the sprite 
    console.log(currentSocket.id + " - " + data);
  });
}

最佳答案

我发现您的 Game 构造函数中的 currentSnake 变量存在问题。该变量的作用域为您的整个构造函数,因此那里只有一个变量,但您试图为每个玩家提供一个单独的变量,但这是行不通的。因此,每次您收到 keyPressed 消息时,您都会对同一条蛇进行操作,无论按键来自哪个玩家。

如果您使用的是 Node.js v6+,则将该构造函数中的 var currentSnake 更改为 let currentSnake,以便该变量的作用域单独作用于 for循环。

constructor(sockets) {
  this.sockets = sockets;
  this.snakes = [];
  var self = this;

  for(var i = 0; i < this.sockets.length; i++) {
    this.snakes[i] = new Snake(i*100 + 100, 200);
    // change these to be declared with let so they are separately scoped 
    //   for each invocation of the for loop
    let currentSnake = this.snakes[i];
    let currentSocket = this.sockets[i];

    currentSocket.on('keyPressed', function(data) {
      currentSnake.updateDirection(data); //Calls a Game method that updates the direction of the sprite 
      console.log(currentSocket.id + " - " + data);
    });
  }
}

或者,如果您运行的是旧版本的 node.js,请切换到 .forEach() 来替换 for 循环,因为这也会创建一个新的单独的循环每次循环调用的范围。

constructor(sockets) {
  this.sockets = sockets;
  this.snakes = [];
  var self = this;

  this.sockets.forEach(function(currentSocket, i) {
    this.snakes[i] = new Snake(i*100 + 100, 200);
    var currentSnake = this.snakes[i];

    currentSocket.on('keyPressed', function(data) {
      currentSnake.updateDirection(data); //Calls a Game method that updates the direction of the sprite 
      console.log(currentSocket.id + " - " + data);
    });
  });
}

关于javascript - Socket.io 从 Node 中的多个套接字接收数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41918468/

相关文章:

node.js - 使用 React.js 虚拟 DOM 在 Node.js 上模拟 Canvas

c++ - 如何使用 read() 在 C++ 套接字中接收超过 40Kb 的数据

c - gethostbyname() 之后的本地 IP

javascript - 如何检查两个正则表达式是否相同?

javascript - 如何在javascript中将文本区域分割成多个部分

javascript - Chrome 内存快照中的保留大小 - 究竟保留了什么?

node.js - Sequelize - 如何设置关联、保存实体并返回保存的实体和关联实体

javascript - 页面跳起来而不是向上滚动

node.js - npm ngrok : Is it safe to use?

php - 如何将Android客户端连接到ReactPHP套接字服务器