IO 处理断开连接事件

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

服务器

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 对象[ person _ name ] ,但它没有。

231766 次浏览

Ok, instead of identifying players by name track with sockets through which they have connected. You can have a implementation like

Server

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

Hope this will help you to think in another way

For those like @sha1 wondering why the OP's code doesn't work -

OP's logic for deleting player at server side is in the handler for DelPlayer event, and the code that emits this event (DelPlayer) is in inside disconnected event callback of client.

The server side code that emits this disconnected event is inside the disconnect event callback which is fired when the socket loses connection. Since the socket already lost connection, disconnected event doesn't reach the client.


Accepted solution executes the logic on disconnect event at server side, which is fired when the socket disconnects, hence works.

Create a Map or a Set, and using "on connection" event set to it each connected socket, in reverse "once disconnect" event delete that socket from the Map we created earlier

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


});

You can also, if you like use socket id to manage your player list like this.

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