Socket.io: Warum löst socket.disconnect() auf der Clientseite kein Trennereignis auf dem Server aus?

Erstellt am 4. Nov. 2015  ·  23Kommentare  ·  Quelle: socketio/socket.io

hier ist mein Code:

clientseitig

 var socket = io.connect('http://' + serverAddress ,{ reconnection: false, forceNew: true  }  );

 socket.emit('monitorAddedNotify' , { video: sourceVideo , socketId: socket.id});

 socket.on('disconnectThatSoc', function(){
    socket.disconnect();
});

serverseitig:

  io.on('connection', function (socket) {
    console.log('a user connected');


    socket.on('disconnect', function () {
        console.log('user disconnected');
    });
 });

die socket.disconnect() Methode funktioniert nicht warum?

Unable to reproduce

Hilfreichster Kommentar

bist du blöd? Sie warten auf eine Ausgabe auf dem Client, aber keine Ausgabe auf dem Server. verpiss dich hier

Alle 23 Kommentare

Soweit ich getestet habe, funktioniert es einwandfrei. Wie können wir das Problem reproduzieren?

Versuchen Sie, die Seite aufzurufen und schnell neu zu laden, indem Sie mehrmals die Taste F5 drücken.

Bei mir funktioniert es auch gut.

Welchen Browser verwendest du? Ich verwende den neuesten Firefox und wenn ich Bage schnell neu lade, funktioniert "Benutzer getrennt" nicht :enttäuscht:

Ich habe das Problem auch. Bei diesen Aktionen kommt es zu einer Verbindungsunterbrechung, die jedoch viel später erfolgt, als der Browser neu gestartet wurde.

Browser: Chrome 55.0.2883.95 (64-Bit)
socket.io: "^1.7.2"

Hallo @Ventaquil. Ich habe das gleiche Problem, dass das Trennereignis nicht ausgelöst wird, wenn F5 gedrückt wird. Hast du das überstanden?

@giathinh910 wird das Ereignis disconnect nicht nach einer bestimmten Verzögerung ausgelöst (das kann mit den Optionen pingTimeout / pingInterval zusammenhängen, die hier dokumentiert sind )?

@darrachequesne Mein Problem ist dasselbe wie das oben beschriebene @ventaquil "Versuchen Sie, die Seite aufzurufen und schnell neu zu laden, indem Sie mehrmals die Taste F5 drücken". Wenn Sie eine Seiten-Socket-Verbindung aktualisieren, wird normalerweise "disconnect" und dann "connect" erneut ausgelöst. Ich verlasse mich auf diese 2 Ereignisse, um die Zahlen der Online-Benutzer zu aktualisieren. Wenn die Seite jedoch schnell genug neu geladen wird, wird die "Verbindung trennen" nicht ausgelöst, was dazu führt, dass eine nicht vorhandene Benutzer-Socket-ID hinzugefügt wird. Diese unwirklichen Personen werden natürlich nach pingTimeout entfernt. Derzeit ändere ich die Methode zum Speichern der Socket-ID, die nur den Online-Benutzer anzeigt, nicht die Nummer des Sockets, und das Problem kann gelöst werden.

Ich habe dieses Problem so gelöst. Ich habe einen Emit-Sender auf dem Client erstellt, der Heartbeat auf dem Server aufruft.
socket.on("heartbeat", function() { // console.log('heartbeat called!'); hbeat[socket.id] = Date.now(); setTimeout(function() { var now = Date.now(); if (now - hbeat[socket.id] > 5000) { console.log('this socket id will be closed ' + socket.id); if (addedUser) { --onlineUsers; removeFromLobby(socket.id); try { // this is the most important part io.sockets.connected[socket.id].disconnect(); } catch (error) { console.log(error) } } } now = null; }, 6000); });

Ich habe diese Codefunktion zum Aufrufen gefunden:

io.sockets.connected[socket.id].disconnect();

Dies passiert immer noch. Es muss nicht F5/refresh sein. Das Öffnen eines Tabs und das schnelle Schließen an einem bestimmten Punkt führt dazu, dass die Trennung nicht ausgelöst wird. Es ist schwer zu reproduzieren, da Sockets sehr schnell sind, insbesondere wenn sie lokal ausgeführt werden. Ich habe festgestellt, dass das Öffnen der Registerkarte im Hintergrund und das Öffnen anderer Registerkarten dazu beigetragen hat, das Problem (lokal) zu reproduzieren. Ich denke, das ist ein wichtiger Fehler, der behoben werden sollte.

Habe hier das gleiche Problem. Dies erstellt Geisterspiele auf meinem Gameserver

Um den Client manuell zu trennen, können Sie möglicherweise eine Funktion mit etwas Emitting verwenden.
Ich weiß nicht, ob das hilft, aber ich glaube, ich habe etwas ... Vielleicht ...

Auftraggeber :

function ManualSocketDisconnect() {
    socket.emit("manual-disconnection", socket.id);

    socket.close();

    console.log("Socket Closed. ");
}

Server :

io.on("connection", function(socket) {
    console.log("User " + socket.id + " Connected. ");

    socket.on("manual-disconnection", function(data) {
        console.log("User Manually Disconnected. \n\tTheir ID: " + data);
    });
});

Entschuldigung, aber ich habe wahrscheinlich einige Lücken in meinem Code hinterlassen. Ich bin kein Profi. 🙁

Ich stehe vor dem gleichen Problem!
Ich werde das Beispiel in ReactJS-ExpressJS geben.

Hier ist die Situation, die das Ereignis auslösen wird und in componentWillUnmount() gekapselt ist.

Ich werde zwei Ereignisse vergleichen, die ich von componentWillUnmount() werde

  1. newMessage :- Dies sendet eine Nachricht an einen bestimmten Raum
  2. disconnect :-(Ich hatte gehofft, dass es funktioniert, aber es funktioniert nicht) Dieser Ereignis-Listener hat einen Rückruf, der die Verbindung trennt. Ich habe ein console.log() enthalten, nur um zu bestätigen, ob der Rückruf ankommt.

Nun, hier gehen wir: -
Klient:-

Diese Ereignisse werden ausgelöst:-

  componentDidMount() {
    console.log(this.props)
    chat.emit('authenticate', {
      token: localStorage.getItem('auth'),
      refreshToken: localStorage.getItem('refresh'),
      projectId: this.props.projectId,
      userId: this.props.userId,
    });
    chat.on('newMessage', (messageData) => {
      console.log('------------newMessageReceived-------------');
      this.props.messageReceived({ messages: this.props.messages, messageData }, () => {
        console.log('callback');
        this.setState({
          messages: this.props.messages
        })
      })
      console.log(messageData);
    })
  }

Das folgende Ereignis wird nicht ausgelöst.

  componentWillUnmount() {
    chat.emit('disconnect','just disconnect);
  }

Das folgende Ereignis wird ausgelöst. (nur testen, ob ein normales Nachrichtenereignis ausgegeben wird)

  componentWillUnmount() {
    chat.emit('newMEssage', {
      messageHeader: {
        sender: {
          user: {
            id: this.props.userId,
            name: this.props.name
          }
        }
      },
      messageBody: 'hello',
    });
  }

Kein Glück

Server:-
Hier ist der Code im expressJS-Backend

//Nach initializeChatSocket wird in app.js aufgerufen

function initializeChatSocket(server) {
  projects.hasMany(projectTeam, { foreignKey: 'projectId' });

  const io = socketIO(server);
  const chat = io.of('/chat').on('connection', function (socket) {
    console.log(
      '----------------------------------------New Chat Connection Established-------------------------------------------------------------------------'
    );

    socket.auth = false;

    socket.on('authenticate', function (data) {
      console.log('\n\n\n\n', 'authenticate called', '\n\n\n\n', data, '\n\n\n');

      try {
        const dummyReq = {
          headers: {
            refreshtoken: data.refreshToken,
          },
        };
        console.log('\n\n\n\n', 'before verify', '\n\n\n\n');
        const userDetails = verifyJWTToken(dummyReq, data.token);
        console.log('\n\n\n\n', 'after verify', '\n\n\n\n');
        socket.userId = userDetails.userId;
        socket.projectId = data.projectId;

        projectTeam
          .findAll({
            where: {
              [Op.and]: {
                projectId: data.projectId,
                userId: data.userId,
              }
            }
          })
          .then(projects => {
            console.log('\n\n\n\n', JSON.stringify(projects), '\n\n\n\n');
            if (projects.length === 1) {
              socket.auth = true;
              socket.join(socket.projectId);
              console.log('User id:- ${userDetails.userId} linked to project id :- ${socket.projectId}');
            } else {
              console.log('User id:- ${userDetails.userId} not linked to project id :- ${socket.projectId}');
              throw { message: 'User not linked to project' };
            }
          });
      } catch (error) {
        console.log(String(error));

        socket.auth = false;
        socket.disconnect(String(error));
      }
    });

    socket.on('disconnectt', function() {
      console.log('Client Disconnecting'); // This is not being fired :/
      socket.removeAllListeners('newMessage');
      socket.removeAllListeners('disconnect');
      socket.removeAllListeners('authenticate');
      socket.removeAllListeners('connection');
      });

    socket.on('newMessage', async function (messageData) {
      console.log('-------------------------New Message----------------------', String(messageData));
      //TODO Save Message in Database

      try {
        socket.broadcast.to(socket.projectId).emit('newMessage', messageData);
        console.log('\n\n\n\n\n broadcast sent\n\n' + JSON.stringify(messageData) + '\n\n\n');
      } catch (error) {
        console.log('\n\n\n\n\n broadcast error\n\n\n\n\n');
        console.log(String(error));

        console.log(error);
        //TODO Handle Message Sending Error
      }
    });

  });
}

Ist dies ein Problem mit dem Browser oder etwas anderem, das ich von der Stack-Overflow-Community fragen muss?

@manjotsk Ich bin mir nicht sicher, ob Sie es inzwischen behoben haben, aber auf Ihrem serverseitigen Code hören Sie auf disconnectt (beachten Sie das doppelte t ), aber Ihr Front-End gibt aus disconnect . Außerdem möchten Sie wahrscheinlich nicht disconnect ausgeben, da dieses Ereignis vom Client zum Server gesendet werden soll, wenn der Client die Verbindung trennt.

Ich habe Code, der darauf angewiesen ist, dass der Socket das Disconnect-Ereignis ausgibt, um doppelte IPS zu verhindern – Benutzer, die meine App neu laden, werden schnell blockiert, weil die Trennung sogar nie ausgelöst wird!

@manjotsk Ich bin mir nicht sicher, ob Sie es inzwischen behoben haben, aber auf Ihrem serverseitigen Code hören Sie auf disconnectt (beachten Sie das doppelte t ), aber Ihr Front-End gibt aus disconnect . Außerdem möchten Sie wahrscheinlich nicht disconnect ausgeben, da dieses Ereignis vom Client zum Server gesendet werden soll, wenn der Client die Verbindung trennt.
disconnectt war ein Betrüger-Alias, den ich benutzte! Vielen Dank für den Hinweis. Ich werde das nochmal auf beiden Seiten prüfen. Und offensichtlich war die Umsetzung falsch! Ich habe eine klarere Sicht! Danke @nathanheffley 👍 :)

@manjotsk Was?

und verwenden Sie nur socket.once statt socket.on
„Kundenebene“.
Beispiel:
socket.on('verbinden')
verwenden
socket.once('connect'
.

gleiche hier meine
socket.on("message") { (dataArray, socketAck) -> Void in

  if let data = dataArray.first as? Data{
    do{
      let objc = try JSONDecoder.init().decode(GetChatConversation.self, from: data)
      completionHandler(objc,nil)
    }
    catch let error{
      return completionHandler(nil,error.localizedDescription)
    }
  }else{
    completionHandler(nil,"Cannot cast Array of Any to Data")
  }
}

nicht den Rückruf zurückrufen, wenn jemand weiß, es mir zu sagen

bist du blöd? Sie warten auf eine Ausgabe auf dem Client, aber keine Ausgabe auf dem Server. verpiss dich hier

Das ist wirklich negative Energie, Ehsan666x.

Ich habe dieses Problem so gelöst. Ich habe einen Emit-Sender auf dem Client erstellt, der Heartbeat auf dem Server aufruft.
hbeat[socket.id] = Date.now();

Ich frage mich, welcher hbeat -Wert von der Clientseite gesendet werden sollte?

Anstelle von socket.disconnect() oder socket.emit('disconnect') versuchen Sie socket.close(); auf der Clientseite und es sollte das Ereignis 'disconnect' auf der Serverseite auslösen. Es hat für mich funktioniert.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen