Socket.IO 处理断开事件

IT技术 javascript socket.io disconnect
2021-02-21 00:48:12

无法处理这个断开连接事件,不知道为什么socket没有发送到客户端/客户端没有响应!

服务器

io.sockets.on('connection', function (socket) {

  socket.on('NewPlayer', function(data1) {

    online = online + 1;
    console.log('Online players : ' + online);
    console.log('New player connected : ' + data1);
    Players[data1] = data1;
    console.log(Players);

  });

  socket.on('DelPlayer', function(data) {

    delete Players[data];
    console.log(Players);
    console.log('Adios' + data);

  });

  socket.on('disconnect', function () {

      socket.emit('disconnected');
      online = online - 1;

  });

});

客户

 var socket = io.connect('http://localhost');

    socket.on('connect', function () { 

        person_name = prompt("Welcome. Please enter your name");

        socket.emit('NewPlayer', person_name);

        socket.on('disconnected', function() {

            socket.emit('DelPlayer', person_name);

        });

    });

正如您所看到的,当客户端断开连接时,应该删除 Array object[person_name],但事实并非如此。

4个回答

好的,而不是通过名称跟踪带有连接的套接字来识别玩家。你可以有一个像

服务器

var allClients = [];
io.sockets.on('connection', function(socket) {
   allClients.push(socket);

   socket.on('disconnect', function() {
      console.log('Got disconnect!');

      var i = allClients.indexOf(socket);
      allClients.splice(i, 1);
   });
});

希望这能帮助你换一种方式思考

当您获得 -1 的值时,这意味着您正在尝试拼接一个不存在的套接字(有人断开连接,但您尚未在您的allClients数组中注册该人)。我建议你只返回:if (i === -1)return;在尝试拼接之前。
2021-04-20 00:48:12
更好地用于allClients.splice(i, 1)删除元素。delete allClients[i]只会将数组位置设置为undefined
2021-04-21 00:48:12
@VinitChouhan 您可能应该针对您的实际问题提出单独的问题。
2021-05-01 00:48:12
这对我不起作用。这里i每次都得到 -1 的值。你能告诉我这是怎么回事吗?
2021-05-03 00:48:12
为什么它起作用了,但是用他们的名字跟踪人的解决方案不起作用?
2021-05-05 00:48:12

对于像@sha1 这样想知道为什么 OP 的代码不起作用的人 -

OP 在服务器端删除播放器的逻辑在DelPlayer事件的处理程序中,而发出此事件 ( DelPlayer)的代码disconnected客户端的内部事件回调中。

发出此disconnected事件的服务器端代码位于disconnect事件回调中,当套接字失去连接时会触发该回调。由于套接字已经失去连接,disconnected事件不会到达客户端。


接受的解决方案disconnect在服务器端的事件上执行逻辑,当套接字断开连接时会触发该逻辑,因此可以工作。

创建一个 Map 或一个 Set,并使用“on connection”事件设置给每个连接的套接字,相反的“一旦断开”事件从我们之前创建的 Map 中删除该套接字

import * as Server from 'socket.io';

const io = Server();
io.listen(3000);

const connections = new Set();

io.on('connection', function (s) {

  connections.add(s);

  s.once('disconnect', function () {
    connections.delete(s);
  });

});

你也可以,如果你喜欢使用套接字 id 来管理你的玩家列表。

io.on('connection', function(socket){
  socket.on('disconnect', function() {
    console.log("disconnect")
    for(var i = 0; i < onlineplayers.length; i++ ){
      if(onlineplayers[i].socket === socket.id){
        console.log(onlineplayers[i].code + " just disconnected")
        onlineplayers.splice(i, 1)
      }
    }
    io.emit('players', onlineplayers)
  })

  socket.on('lobby_join', function(player) {
    if(player.available === false) return
    var exists = false
    for(var i = 0; i < onlineplayers.length; i++ ){
      if(onlineplayers[i].code === player.code){
        exists = true
      }
    }
    if(exists === false){
      onlineplayers.push({
        code: player.code,
        socket:socket.id
      })
    }
    io.emit('players', onlineplayers)
  })

  socket.on('lobby_leave', function(player) {
    var exists = false
    for(var i = 0; i < onlineplayers.length; i++ ){
      if(onlineplayers[i].code === player.code){
        onlineplayers.splice(i, 1)
      }
    }
    io.emit('players', onlineplayers)
  })
})