Socket.io: mengapa socket.disconnect() di sisi klien tidak mengaktifkan acara disconnect di server?

Dibuat pada 4 Nov 2015  ·  23Komentar  ·  Sumber: socketio/socket.io

ini kode saya:

sisi klien

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

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

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

sisi server:

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


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

metode socket.disconnect() tidak berfungsi mengapa?

Unable to reproduce

Komentar yang paling membantu

Apakah kamu bodoh? Anda sedang menunggu emisi di klien tetapi tidak ada emisi di server. pergi dari sini

Semua 23 komentar

Sejauh yang saya uji, berfungsi dengan baik. Bagaimana kita bisa mereproduksi masalah?

Coba masuk halaman dan muat ulang cepat dengan menekan tombol F5 berkali-kali.

Ini bekerja dengan baik untuk saya juga.

Peramban mana yang Anda gunakan? Saya menggunakan Firefox terbaru dan ketika saya memuat ulang bage "pengguna terputus" tidak berfungsi :kecewa:

Saya punya masalah juga. Dalam tindakan ini, pemutusan, tetapi datang lebih lambat dari browser restart.

Peramban: Chrome 55.0.2883.95 (64-bit)
socket.io: "^1.7.2"

Hai @ventaquil. Saya masalah yang sama bahwa acara disconnect tidak menembak saat memegang F5. Apakah Anda sudah mengatasi ini?

@giathinh910 bukankah acara disconnect dipicu setelah penundaan yang diberikan (yang mungkin terkait dengan opsi pingTimeout / pingInterval , didokumentasikan di sini )?

@darrachequesne Masalah saya sama dengan @ventaquil yang dijelaskan di atas "Coba masuk halaman dan muat ulang cepat dengan menekan tombol F5 berkali-kali". Biasanya ketika Anda me-refresh koneksi soket halaman akan mengeluarkan "disconnect" lalu "connect" lagi. Saya mengandalkan 2 acara ini untuk memperbarui jumlah pengguna online. Namun jika halaman memuat ulang cukup cepat, "putuskan" tidak akan menyala, yang menyebabkan beberapa id soket pengguna yang tidak ada ditambahkan. Orang-orang yang tidak nyata ini tentu saja akan dihapus setelah pingTimeout. Saat ini saya mengubah cara menyimpan id soket yang hanya akan menunjukkan pengguna online, bukan jumlah soket dan masalah dapat diselesaikan.

Saya menangani masalah ini dengan cara ini. Saya telah membuat pengirim pemancar di klien yang memanggil detak jantung di server.
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); });

Saya menemukan fungsi kode ini untuk memanggil:

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

Ini masih terjadi. Tidak harus F5/refresh. Membuka tab dan menutupnya segera dengan cepat pada tahap tertentu, menyebabkan disconnect tidak terpicu. Sulit untuk mereproduksi karena soket sangat cepat, terutama saat dijalankan secara lokal. Saya perhatikan membuka tab di latar belakang dan membuka tab lain membantu mereproduksi masalah (secara lokal). Saya pikir ini adalah bug penting yang harus diatasi.

Memiliki masalah yang sama di sini. Ini membuat game hantu di server game saya

Mungkin untuk memutuskan sambungan klien secara manual, Anda dapat menggunakan fungsi dengan beberapa pemancar.
Saya tidak tahu apakah ini akan membantu, tetapi saya pikir saya mendapatkan sesuatu... Mungkin...

klien :

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

Maaf, tapi saya mungkin meninggalkan beberapa lubang di kode saya. Saya tidak profesional. 🙁.

Saya menghadapi masalah yang sama!
Saya akan memberikan contoh di ReactJS-ExpressJS.

Inilah situasinya, yang akan mengaktifkan acara, dan dienkapsulasi dalam componentWillUnmount() .

Saya akan membandingkan dua acara, yang akan saya aktifkan dari componentWillUnmount()

  1. newMessage :- ini akan menyiarkan pesan ke ruangan tertentu
  2. disconnect :-(Saya berharap itu akan berhasil, tetapi tidak) Pendengar acara ini memiliki panggilan balik yang akan terputus. Saya telah memuat console.log() hanya untuk mengonfirmasi jika panggilan balik berhasil.

Sekarang, ini dia:-
Klien:-

Peristiwa ini dipecat:-

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

Acara berikut tidak akan menyala.

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

Acara berikut akan dipicu. (hanya menguji apakah acara pesan normal memancarkan)

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

Tidak Beruntung

Server:-
Berikut adalah kode di backend expressJS

//Mengikuti initializeChatSocket dipanggil di app.js

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

  });
}

Apakah ini masalah dengan browser atau hal lain yang perlu saya tanyakan dari komunitas stack-overflow?

@manjotsk Saya tidak yakin apakah Anda sudah memperbaikinya sekarang, tetapi pada kode sisi server Anda, Anda mendengarkan disconnectt (perhatikan ganda t ) tetapi front-end Anda memancarkan disconnect . Juga, Anda mungkin tidak ingin memancarkan disconnect karena acara tersebut seharusnya dikirim dari klien ke server saat klien terputus.

Saya memiliki kode yang bergantung pada soket yang memancarkan acara pemutusan untuk mencegah duplikat ips-- pengguna yang memuat ulang aplikasi saya dengan cepat diblokir karena pemutusan bahkan tidak pernah menyala!

@manjotsk Saya tidak yakin apakah Anda sudah memperbaikinya sekarang, tetapi pada kode sisi server Anda, Anda mendengarkan disconnectt (perhatikan ganda t ) tetapi front-end Anda memancarkan disconnect . Juga, Anda mungkin tidak ingin memancarkan disconnect karena acara tersebut seharusnya dikirim dari klien ke server saat klien terputus.
disconnectt adalah alias palsu yang saya gunakan! Terima kasih telah menunjukkan. Saya akan memeriksa ulang dengan ini di kedua sisi. Dan, jelas, implementasinya salah! Saya mendapat pandangan yang lebih jelas! Terima kasih @nathanheffley 👍 :)

@manjotsk Apa?

dan hanya gunakan socket.once sebagai gantinya socket.on
"tingkat pelanggan."
contoh:
socket.on('koneksi')
menggunakan
socket.once('menghubungkan'
.

sama di sini saya
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")
  }
}

jangan kembalikan panggilan balik jika ada yang tahu beri tahu saya

Apakah kamu bodoh? Anda sedang menunggu emisi di klien tetapi tidak ada emisi di server. pergi dari sini

Itu adalah energi negatif yang nyata, Ehsan666x.

Saya menangani masalah ini dengan cara ini. Saya telah membuat pengirim pemancar di klien yang memanggil detak jantung di server.
hbeat[socket.id] = Tanggal.sekarang();

Saya ingin tahu nilai hbeat apa yang harus dikirim dari sisi klien?

Alih-alih socket.disconnect() atau socket.emit('disconnect') coba socket.close(); di sisi klien dan itu akan memicu acara 'disconnect' di sisi server. Itu berhasil untuk saya.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat