memaksa klien memutuskan sambungan dari server dengan socket.io dan nodejs

117

Apakah ada cara untuk memutuskan klien dengan SocketIO, dan benar-benar menutup koneksi? Jadi, jika seseorang terhubung ke server saya, dan saya ingin menutup koneksi antara mereka dan server saya, bagaimana saya akan melakukannya?

Daniel Kenney
sumber

Jawaban:

146

Edit: Ini sekarang mungkin

Anda sekarang dapat memanggil socket.disconnect()di sisi server .

Jawaban asli saya:

Ini belum memungkinkan.

Jika Anda membutuhkannya juga, pilih / komentari masalah ini .

nh2
sumber
Jadi saya melakukan itu, dan itu memaksa klien untuk memutuskan sambungan, sayangnya tampaknya klien langsung menyambung kembali. Apakah saya salah paham tentang apa yang sedang terjadi, atau apakah itu perilaku yang diharapkan?
kybernetikos
@kybernetikos Ya, saya mengharapkan ini - klien dapat memilih apa yang akan mereka lakukan dengan miliknya sendiri. Seringkali, Anda ingin menendang sisi lain dari koneksi saat ini , katakanlah karena batas waktu auth - menghubungkan kembali setelah ini mungkin akan diinginkan.
nh2
Jadi, apakah Anda tahu cara memberi tahu klien 'pergi dan saya sungguh-sungguh'? Saya berpikir dari sudut pandang untuk menentukan bahwa klien berperilaku buruk dan tidak ingin mereka menggunakan sumber daya di server saya.
kybernetikos
@kybernetikos Tidak, Anda tidak dapat melakukan itu (umumnya). Jika Anda memprogram sisi klien, tentu saja Anda dapat mengimplementasikan logika apa pun yang Anda inginkan, misalnya menghentikannya agar tidak tersambung kembali. Jika tidak, harus berulang kali menendang pengguna, atau jika benar-benar perlu, gunakan teknik pemblokiran standar; semakin rendah level ini diterapkan (mis. iptables), semakin banyak sumber daya yang akan Anda hemat. Dalam banyak kasus, hanya dengan menendang klien saja sudah cukup, karena socketio tidak terhubung secepat itu, dan jika seseorang benar-benar ingin melakukan DoS kepada Anda, mereka tetap memiliki cara lain (misalnya mendownload halaman dari Anda).
nh2
1
@ManishSapkal Anda mungkin harus membuka pertanyaan baru untuk itu, tidak cocok dengan komentar.
nh2
15

socket.disconnect() hanya dapat digunakan di sisi klien, bukan di sisi server.

Client.emit('disconnect')memicu peristiwa pemutusan hubungan di server, tetapi tidak secara efektif memutuskan klien. Klien tidak mengetahui pemutusan hubungan.

Jadi pertanyaannya tetap: bagaimana cara memaksa klien untuk memutuskan koneksi dari sisi server?

Fabien
sumber
1
Anda tidak perlu menelepon Client.emit('disconnect')secara manual lagi dengan versi socket.io terbaru, sekarang ada sisi server socket.disconnect()(lihat jawaban saya).
nh2
5
Karena pembaruan terkini, amswer Anda salah sekarang, karenanya -1.
corazza
Saya setuju, jawaban ini sudah tidak valid lagi, karena sekarang sudah socket.disconnect()bisa digunakan di sisi server juga.
Vassilis Barzokas
@VassilisBarzokas Bagaimana jika saya ingin panggilan balik dan meneruskan beberapa parameter ke panggilan balik setelah disconnect()fungsi selesai?
pria baru
membuat sekumpulan pesan yang disepakati di mana satu pihak memberi tahu pihak lain bahwa mereka ingin memutuskan sambungan, lalu melakukan apa yang perlu Anda lakukan, dan kemudian benar-benar memutuskan sambungan.
Mike 'Pomax' Kamermans
8

Ada alasan mengapa Anda tidak dapat meminta server mengirimkan pesan ke klien yang membuatnya memanggil fungsi putuskan sambungan?

Pada klien:

socket.emit('forceDisconnect');

Di Server:

socket.on('forceDisconnect', function(){
    socket.disconnect();
});
quahada
sumber
7
Karena kode sisi klien tidak pernah dapat diandalkan untuk berfungsi persis seperti yang Anda inginkan. Pengguna dapat dengan mudah memodifikasinya.
Kaustubh Karkare
4

Dengan asumsi soket Anda bernama soket, gunakan:

socket.disconnect()
Erik
sumber
2
Sayangnya, ini tidak berhasil. Saya mencoba menutup koneksi ke klien tertentu dari sisi server.
Daniel Kenney
4

Bagi mereka yang menemukan ini di google - ada solusi untuk ini sekarang:

Socket.disconnect()menendang klien (sisi server). Tidak ada kesempatan bagi klien untuk tetap terhubung :)

Sascha Gehlich
sumber
Bagaimana cara menemukan soket pengguna yang terputus di server?
Manish Sapkal
Manish: Dengarkan acara soket disconnectuntuk mengetahui apakah sudah terputus. Bisa juga closeacaranya, saya kurang yakin. Lihat dokumentasi socket.io untuk informasi lebih lanjut tentang ini.
Sascha Gehlich
3

Dalam kasus saya, saya ingin meruntuhkan koneksi yang mendasarinya dalam hal ini saya harus menelepon socket.disconnect(true)seperti yang Anda lihat diperlukan dari sumbernya di sini

Duncan
sumber
2

client._onDisconnect() harus bekerja

Emmerman
sumber
1
Ini bekerja dengan sempurna .. Saya mempertahankan pemetaan saya sendiri untuk klien .. menggunakan pemetaan itu ... dengan mudah memutuskan hubungan klien .. tepuk tangan
Arenstar
1

Socket.io menggunakan pola EventEmitter untuk memutuskan / menghubungkan / memeriksa detak jantung sehingga Anda dapat melakukannya. Client.emit('disconnect');

Anthony Wlodarski
sumber
1

Ini tidak berhasil untuk saya:

`socket.disconnect()` 

Ini berhasil untuk saya:

socket.disconnect(true)

Menyerahkan trueakan menutup koneksi yang mendasari ke klien dan bukan hanya namespace klien yang terhubung ke Dokumentasi Socket IO .


Contoh kasus penggunaan: Klien memang terhubung ke server soket web dengan token akses yang tidak valid (token akses diserahkan ke server soket web dengan parameter koneksi). Server soket web memberi tahu klien bahwa ia akan menutup koneksi, karena token aksesnya tidak valid:

// (1) the server code emits
socket.emit('invalidAccessToken', function(data) {
    console.log(data);       // (4) server receives 'invalidAccessTokenEmitReceived' from client
    socket.disconnect(true); // (5) force disconnect client 
});

// (2) the client code listens to event
// client.on('invalidAccessToken', (name, fn) => { 
//     // (3) the client ack emits to server
//     fn('invalidAccessTokenEmitReceived');
// });
Baran Emre
sumber
0

Saya menggunakan client.emit('disconnect')+ client.removeAllListeners()untuk klien yang terhubung untuk mengabaikan semua acara setelah terputus

skyman
sumber
0

Saya menggunakan di sisi klien socket.disconnect();

client.emit('disconnect') didnt work for me
yonia
sumber
0

gunakan:

socket.Disconnect () // ok

jangan gunakan :

socket.disconnect ()

m-tech
sumber
0

Anda dapat melakukannya socket = undefineddengan menghapus soket mana yang telah Anda sambungkan. Jadi ketika ingin terhubung lakukan socket (url)

Jadi akan terlihat seperti ini

const socketClient = require('socket.io-client');

let socket;

// Connect to server
socket = socketClient(url)

// When want to disconnect
socket = undefined;
Saurabh Gupta
sumber
-1

Tambahkan koneksi soket baru ke array dan kemudian ketika Anda ingin menutup semua - loop melaluinya dan putuskan. (sisi server)

var socketlist = [];

   io.sockets.on('connection', function (socket) {
        socketlist.push(socket);  
        //...other code for connection here..
   });


    //close remote sockets
    socketlist.forEach(function(socket) {        
        socket.disconnect();                      
    });    
PodTech.io
sumber