Socket.IO behandelt Trennungsereignis


87

Kann dieses Trennungsereignis nicht behandeln, weiß nicht, warum Socket nicht an den Client gesendet wird / Client antwortet nicht!

Server

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;

  });

});

Klient

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

        });

    });

Wie Sie sehen können, sollte das Array-Objekt [person_name] gelöscht werden, wenn ein Client die Verbindung trennt, dies ist jedoch nicht der Fall


Versuchen Sie es besser anders herum, löschen Sie zuerst den Player und trennen Sie die Verbindung. Denn sobald Sie die Verbindung zum Server getrennt haben, kann der Server das vom Client ausgegebene Ereignis nicht mehr empfangen. Behalten Sie den Sockel im Auge und nicht den Player, mit dem Sie die Spieler leicht entfernen können.
Code-Jaff

Wie soll ich den Player löschen und dann die Verbindung trennen? Woher weiß ich, wann der Player die Verbindung trennen wird?
Raggaer

4
sollte das Ereignis auf dem Client nicht 'disconnect'statt sein 'disconnected'?
Sherlock

1
@Sherlock im ursprünglichen Client-Code von OP versuchten sie, ein benutzerdefiniertes Ereignis abzuhören, das sie serverseitig für nicht verbundene Logik auslösten. 'Disconnect' ist zwar das integrierte Disconnect-Ereignis, trägt jedoch nicht direkt zu dem aufgetretenen Problem bei.
Jon Church

Antworten:


166

Ok, anstatt Spieler anhand des Namens mit Sockeln zu identifizieren, über die sie eine Verbindung hergestellt haben. Sie können eine Implementierung wie haben

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

Ich hoffe, dies wird Ihnen helfen, anders zu denken


88
Besser allClients.splice(i, 1)zum Löschen eines Elements verwenden. delete allClients[i]wird nur die Array-Position aufundefined
Yves

1
Warum funktioniert es, aber die Lösung zur Verfolgung von Personen mit ihren Namen funktioniert nicht?
Sha1

Das funktioniert bei mir nicht. Hier wurde ijedes Mal der Wert -1 angegeben. Kannst du mir sagen, was los ist?
Vinit Chouhan

1
@ VinitChouhan sollten Sie wahrscheinlich separate Frage mit Ihrem tatsächlichen Problem stellen.
Code-Jaff

Wenn Sie den Wert -1 erhalten, bedeutet dies, dass Sie versuchen, einen nicht vorhandenen Socket zu verbinden (jemand trennt die Verbindung, aber Sie haben die Person noch nicht in Ihrem allClientsArray registriert ). Ich schlage vor, Sie kehren einfach zurück: if (i === -1)return;bevor Sie versuchen, es zu spleißen.
Koen B.

21

Für diejenigen wie @ sha1, die sich fragen, warum der OP-Code nicht funktioniert -

Die Logik von OP zum Löschen des Players auf der Serverseite befindet sich im Handler für das DelPlayerEreignis, und der Code, der dieses Ereignis ( DelPlayer) disconnectedausgibt, befindet sich im Ereignisrückruf des Clients.

Der serverseitige Code, der dies ausgibt disconnected Ereignis , befindet sich im disconnectEreignisrückruf, der ausgelöst wird, wenn der Socket die Verbindung verliert. Da der Socket bereits die Verbindung verloren hat, erreicht das disconnectedEreignis den Client nicht.


Akzeptierte Lösung führt die Logik auf disconnectEreignis auf der Serverseite aus, die ausgelöst wird, wenn der Socket getrennt wird, und funktioniert daher.


5

Erstellen Sie eine Karte oder einen Satz und löschen Sie diesen Socket mithilfe des Ereignisses "Bei Verbindung", das für jeden verbundenen Socket festgelegt ist, in umgekehrter Reihenfolge "Einmal trennen" aus der zuvor erstellten Karte

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

});

1
Und man würde eine detaillierte Antwort mit Erklärungen und Kommentaren von einem Veteranen erwarten, aber ich denke, wir müssen uns mit nur einer Menge Code
zufrieden geben

Lassen Sie mich wissen, wenn Sie Fragen haben, ich kann mich nicht erinnern, die Antwort geschrieben zu haben
Alexander Mills

1
Ich habe eigentlich keine Frage. Es war nur eine konstruktive Kritik an einem Autor, der es besser versteht, Kommentare und Platzbeschreibungen in einer Antwort zu verwenden, damit jeder (zumindest die meisten) Ihr Beispiel verstehen kann, ohne Sie zu nerven. Wie auch immer, frohes neues Jahr ..
Cemal

0

Sie können auch, wenn Sie möchten, die Socket-ID verwenden, um Ihre Spielerliste wie folgt zu verwalten.

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)
  })
})
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.