wymuś odłączenie klienta od serwera za pomocą socket.io i nodejs

117

Czy istnieje sposób na odłączenie klienta za pomocą SocketIO i dosłowne zamknięcie połączenia? Więc jeśli ktoś jest podłączony do mojego serwera i chcę zamknąć połączenie między nim a moim serwerem, jak mam to zrobić?

Daniel Kenney
źródło

Odpowiedzi:

146

Edycja: jest to teraz możliwe

Możesz teraz po prostu zadzwonić socket.disconnect()po stronie serwera .

Moja pierwotna odpowiedź:

Nie jest to jeszcze możliwe.

Jeśli również tego potrzebujesz, zagłosuj / skomentuj w tej sprawie .

nh2
źródło
Więc robię to i zmusza to klienta do rozłączenia, niestety okazuje się, że klient po prostu natychmiast łączy się ponownie. Czy źle rozumiem, co się dzieje, czy jest to oczekiwane zachowanie?
kybernetikos
@kybernetikos Tak, spodziewałbym się tego - klient może przecież zdecydować, co zrobić ze swoim. Często chcesz wyrzucić drugą stronę z bieżącego połączenia, powiedzmy z powodu przekroczenia limitu czasu uwierzytelniania - ponowne połączenie po tym prawdopodobnie byłoby nawet pożądane.
nh2
Więc czy znasz jakiś sposób na powiedzenie klientowi „odejdź i naprawdę mam to na myśli”? Myślę z punktu widzenia ustalenia, że ​​klient zachowuje się źle i nie chce, aby zużywał zasoby na moim serwerze.
kybernetikos
@kybernetikos Nie, nie możesz tego zrobić (ogólnie). Jeśli jednak programujesz po stronie klienta, możesz oczywiście zaimplementować dowolną logikę, np. Uniemożliwić ponowne połączenie. Jeśli nie, musisz wielokrotnie kopać użytkowników lub, jeśli to naprawdę konieczne, zastosować standardowe techniki blokowania; im niższy poziom są one wdrożone (np. iptables), tym więcej zasobów zaoszczędzisz. W większości przypadków po prostu wyrzucenie klienta powinno wystarczyć, ponieważ socketio nie łączy się tak szybko, a jeśli ktoś naprawdę chce cię zrobić, to i tak ma inne sposoby (np. Pobieranie stron od ciebie).
nh2
1
@ManishSapkal Powinieneś prawdopodobnie otworzyć nowe pytanie, które nie pasuje do komentarzy.
nh2
15

socket.disconnect() może być używany tylko po stronie klienta, a nie po stronie serwera.

Client.emit('disconnect')wyzwala zdarzenie rozłączenia na serwerze, ale nie rozłącza skutecznie klienta. Klient nie wie o rozłączeniu.

Pozostaje więc pytanie: jak zmusić klienta do odłączenia się od serwera?

Fabien
źródło
1
Nie musisz Client.emit('disconnect')już dzwonić ręcznie z ostatnimi wersjami socket.io, jest teraz strona serwera socket.disconnect()(zobacz moją odpowiedź).
nh2
5
Z powodu ostatnich aktualizacji twoja odpowiedź jest teraz niepoprawna, stąd -1.
corazza
Zgadzam się, ta odpowiedź nie jest już aktualna, ponieważ teraz socket.disconnect()można jej używać również po stronie serwera.
Vassilis Barzokas
@VassilisBarzokas A co, jeśli chcę wywołać zwrotne i przekazać niektóre parametry do funkcji zwrotnej po zakończeniu disconnect()funkcji?
newguy
utwórz uzgodniony zestaw wiadomości, w których jedna strona informuje drugą stronę, że chce się rozłączyć, a następnie zrób to, co musisz zrobić, a następnie faktycznie się rozłączy.
Mike 'Pomax' Kamermans
8

Czy jest jakiś powód, dla którego serwer nie może wysłać wiadomości do klienta, która powoduje wywołanie funkcji rozłączenia?

Na kliencie:

socket.emit('forceDisconnect');

Na serwerze:

socket.on('forceDisconnect', function(){
    socket.disconnect();
});
quahada
źródło
7
Ponieważ nigdy nie można polegać na kodzie po stronie klienta, który działa dokładnie tak, jak chcesz. Użytkownicy mogą go łatwo modyfikować.
Kaustubh Karkare
4

Zakładając nazwane gniazdo twojego gniazda, użyj:

socket.disconnect()
Erik
źródło
2
Niestety to nie działa. Próbuję zamknąć połączenie z określonym klientem po stronie serwera.
Daniel Kenney,
4

Dla tych, którzy znaleźli to w Google - teraz jest na to rozwiązanie:

Socket.disconnect()kopie klienta (po stronie serwera). Klient nie ma szans na pozostanie w kontakcie :)

Sascha Gehlich
źródło
Jak znaleźć gniazdo użytkownika, który jest odłączony na serwerze?
Manish Sapkal
Manish: nasłuchuj disconnectzdarzenia gniazda, aby dowiedzieć się, czy zostało rozłączone. Może to być również closewydarzenie, nie jestem do końca pewien. Więcej informacji na ten temat można znaleźć w dokumentacji socket.io.
Sascha Gehlich
3

W moim przypadku chciałem zerwać podstawowe połączenie, w którym to przypadku musiałem zadzwonić, socket.disconnect(true)jak widać, jest potrzebne ze źródła tutaj

Duncan
źródło
2

client._onDisconnect() powinno działać

Emmerman
źródło
1
Działa to doskonale .. Im utrzymać własne mapowanie dla klientów .. użyciu tego mapowania ... łatwo odłączania klientów .. wiwaty
Arenstar
1

Socket.io używa wzorca EventEmitter do rozłączania / łączenia / sprawdzania pulsu, więc możesz to zrobić. Client.emit('disconnect');

Anthony Wlodarski
źródło
1

To nie zadziałało dla mnie:

`socket.disconnect()` 

To zadziałało dla mnie:

socket.disconnect(true)

Przekazanie truespowoduje zamknięcie podstawowego połączenia z klientem, a nie tylko przestrzeni nazw, do której klient jest podłączony do dokumentacji Socket IO .


Przykładowy przypadek użycia: klient połączył się z serwerem gniazda sieciowego z nieprawidłowym tokenem dostępu (token dostępu przekazany do serwera gniazda sieciowego z parametrami połączenia). Serwer gniazda sieciowego powiadamia klienta, że ​​zamierza zamknąć połączenie z powodu jego nieprawidłowego tokenu dostępu:

// (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
źródło
0

Używam client.emit('disconnect')+ client.removeAllListeners()dla podłączonego klienta do ignorowania wszystkich zdarzeń po rozłączeniu

skyman
źródło
0

Używam po stronie klienta socket.disconnect();

client.emit('disconnect') didnt work for me
jonia
źródło
0

posługiwać się :

socket.Disconnect () // ok

nie używać :

socket.disconnect ()

m-tech
źródło
0

Możesz to zrobić socket = undefinedw wymazaniu, które gniazdo podłączyłeś. Więc kiedy chcesz się połączyć z gniazdem (url)

Więc to będzie wyglądać tak

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

let socket;

// Connect to server
socket = socketClient(url)

// When want to disconnect
socket = undefined;
Saurabh Gupta
źródło
-1

Dodaj nowe połączenia gniazd do macierzy, a gdy chcesz zamknąć wszystko - zapętl je i rozłącz. (po stronie serwera)

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
źródło