Socket.IO menangani peristiwa pemutusan hubungan

90

Tidak dapat menangani peristiwa pemutusan hubungan ini, tidak tahu mengapa soket tidak dikirim ke klien / klien tidak merespons!

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;

  });

});

Klien

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

        });

    });

Seperti yang Anda lihat ketika klien memutuskan hubungan, objek Array [person_name] harus dihapus, tetapi tidak

Raggaer
sumber
Lebih baik Anda mencoba cara lain, pertama hapus pemutar lalu putuskan sambungan. Karena setelah Anda terputus dari server, server tidak akan dapat menerima acara yang dipancarkan klien. Lacak soket daripada pemutar, yang dengannya Anda dapat mengeluarkan pemain dengan mudah.
code-jaff
Bagaimana cara menghapus pemutar dan kemudian memutuskan sambungan? bagaimana saya tahu kapan pemain akan memutuskan koneksi ?.
Raggaer
4
seharusnya tidak acara pada klien menjadi 'disconnect'bukan 'disconnected'?
Sherlock
1
@Sherlock dalam kode klien asli OP, mereka mencoba untuk mendengarkan acara khusus yang mereka picu di sisi server untuk logika terputus. 'putuskan sambungan' memang merupakan peristiwa terputus yang ada di dalamnya, tetapi tidak berkontribusi langsung pada masalah yang mereka alami.
Gereja Jon

Jawaban:

173

Oke, alih-alih mengidentifikasi pemain dengan jalur nama dengan soket yang mereka hubungkan. Anda dapat memiliki implementasi seperti

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

Semoga ini akan membantu Anda untuk berpikir dengan cara lain

kode-jaff
sumber
92
Lebih baik gunakan allClients.splice(i, 1)untuk menghapus elemen. delete allClients[i]hanya akan mengatur posisi array keundefined
Yves
1
Mengapa berhasil, tetapi solusi pelacakan orang dengan nama mereka tidak berfungsi?
sha1
Ini tidak berhasil untuk saya. Di sini imendapat nilai -1 setiap kali. Bisakah Anda memberi tahu saya apa yang sedang terjadi.
Vinit Chouhan
1
@VinitChouhan Anda mungkin harus mengajukan pertanyaan terpisah dengan masalah Anda yang sebenarnya.
code-jaff
Ketika Anda mendapatkan nilai -1, itu berarti Anda mencoba untuk menyambungkan soket yang tidak ada (seseorang memutus tetapi Anda belum mendaftarkan orang itu ke dalam allClientslarik Anda ). Saya sarankan Anda kembali: if (i === -1)return;sebelum mencoba menyambungkannya.
Koen B.
23

Bagi mereka seperti @ sha1 yang bertanya-tanya mengapa kode OP tidak berfungsi -

Logika OP untuk menghapus pemain di sisi server ada di handler untuk DelPlayeracara, dan kode yang mengeluarkan acara ini ( DelPlayer) ada di dalam disconnectedacara callback klien.

Kode sisi server yang memancarkan disconnectedperistiwa ini ada di dalam disconnectperistiwa callback yang dipicu saat soket kehilangan koneksi. Karena soket sudah kehilangan koneksi, disconnectedacara tidak mencapai klien.


Solusi yang diterima mengeksekusi logika pada disconnectacara di sisi server, yang ditembakkan ketika soket terputus, karenanya berfungsi.

TJ
sumber
6

Buat Peta atau Set, dan gunakan acara "on connection" yang disetel untuk itu setiap soket yang terhubung, sebaliknya acara "sekali putuskan" hapus soket itu dari Peta yang kita buat sebelumnya

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

});
Alexander Mills
sumber
1
Dan orang akan mengharapkan jawaban rinci dengan penjelasan dan komentar dari seorang veteran, tapi saya kira kita harus puas hanya dengan sekumpulan kode
Cemal
beri tahu saya jika Anda memiliki pertanyaan, saya tidak ingat pernah menulis jawabannya
Alexander Mills
1
Saya sebenarnya tidak punya pertanyaan. Itu hanya kritik yang membangun bagi seorang penulis, yang lebih tahu menggunakan komentar dan deskripsi tempat dalam jawaban untuk membiarkan siapa pun (setidaknya paling tidak) untuk memahami contoh Anda tanpa mengganggu Anda. Anyways, selamat tahun baru ..
Cemal
0

Anda juga bisa, jika Anda suka menggunakan id soket untuk mengelola daftar pemain Anda seperti ini.

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)
  })
})
www-data
sumber