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ć?

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 .


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?


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

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

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


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


2

client._onDisconnect() powinno działać


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


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

0

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


0

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

client.emit('disconnect') didnt work for me

0

posługiwać się :

socket.Disconnect () // ok

nie używać :

socket.disconnect ()


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;

-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();                      
    });    
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.