简体   繁体   English

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

[英]Socket.io receiving data from multiple sockets in Node

I started developing in Node just a couple of days ago. 几天前,我开始在Node上进行开发。 I'm currently developing an online game that uses Node as server-side application. 我目前正在开发一个在线游戏,该游戏使用Node作为服务器端应用程序。 This application simply provides the .html and .js files to the client and handles the logic of the game. 该应用程序仅向客户端提供.html和.js文件,并处理游戏逻辑。 I'm using Socket.io to exchange data with the clients. 我正在使用Socket.io与客户端交换数据。 When a new client connects to the server through Socket.io the program looks for a room (array of objects containing the sockets for the two users and the game object that handles the logic) that has an empty space and places the user (registering the socket) in it. 当新的客户端通过Socket.io连接到服务器时,程序会寻找一个空间(放置两个用户的套接字以及用于处理逻辑的游戏对象的对象数组),该房间有一个空白空间并放置用户(注册插座)。 I've been able to correctly send to each client the position of the sprites, but I have a problem with retrieving data from each socket: If I try to send some data from the client to the server, that data flows through only one of the two sockets, no matter which client is sending that. 我已经能够正确地将每个精灵的位置发送给每个客户端,但是我从每个套接字检索数据时遇到了问题:如果我尝试将一些数据从客户端发送到服务器,则该数据仅流经两个套接字,无论哪个客户端发送该套接字。

Initializing the room array 初始化房间阵列

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 handling the connections 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);
  });
});

Adding the clients to rooms 将客户添加到房间

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;
    }
  }
}

Creating the Game object when a room if full (and destructing it when a player leaves) 如果房间满了就创建游戏对象(并在玩家离开时破坏它)

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');
    }
  }
}

Receiving data in the Game class 在游戏类中接收数据

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);
  });
}

I see a problem with the currentSnake variable in your Game constructor. 我在您的Game构造函数中看到currentSnake变量有问题。 That variable is scoped to your whole constructor so there's only one variable there, but you're trying to have a separate variable for each player and that isn't working. 该变量的作用域是整个构造函数,因此那里只有一个变量,但是您正试图为每个播放器设置一个单独的变量,并且该变量不起作用。 Thus, every time you get the keyPressed message, you operation on the same snake, no matter which player the key came from. 因此,每当您收到keyPressed消息时,无论密钥来自哪个玩家,您都对同一条蛇进行操作。

If you're using node.js v6+, then change var currentSnake in that constructor to let currentSnake so that the variable is separately scoped to each invocation of the for loop. 如果您使用的是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);
    });
  }
}

Or, if you are running an older version of node.js, switch to .forEach() to replace the for loop as this will also make a new separate scope for each invocation of the loop. 或者,如果您正在运行旧版本的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);
    });
  });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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