forçar a desconexão do cliente do servidor com socket.io e nodejs

117

Existe alguma maneira de desconectar um cliente com SocketIO e literalmente fechar a conexão? Portanto, se alguém estiver conectado ao meu servidor e eu quiser encerrar a conexão entre essa pessoa e meu servidor, como devo proceder para fazer isso?

Daniel Kenney
fonte

Respostas:

145

Editar: Isso agora é possível

Agora você pode simplesmente ligar socket.disconnect()no lado do servidor .

Minha resposta original:

Isso ainda não é possível.

Se você também precisar, vote / comente sobre este assunto .

nh2
fonte
Então, estou fazendo isso e força o cliente a se desconectar; infelizmente, parece que o cliente simplesmente se reconecta imediatamente. Estou entendendo mal o que está acontecendo ou esse é o comportamento esperado?
kybernetikos
@kybernetikos Sim, eu esperava isso - afinal, o cliente pode escolher o que fazer com os seus. Freqüentemente, você deseja chutar o outro lado da conexão atual , digamos por causa de um tempo limite de autenticação - uma reconexão após isso provavelmente seria até desejável.
nh2
Então, você conhece alguma maneira de dizer ao cliente 'vá embora e eu realmente quero dizer isso'? Estou pensando do ponto de vista de determinar que um cliente está se comportando mal e não querendo que ele esgote recursos do meu servidor.
kybernetikos
@kybernetikos Não, você não pode fazer isso (geralmente). Porém, se você estiver programando o lado do cliente, é claro que pode implementar qualquer lógica que desejar, por exemplo, interromper a reconexão. Se não, tem que chutar repetidamente os usuários, ou se realmente necessário, recorrer a técnicas de bloqueio padrão; quanto mais baixo eles forem implementados (por exemplo iptables), mais recursos você economizará. Na maioria dos casos, simplesmente chutar o cliente deve ser suficiente, já que o socketio não se conecta tão rapidamente, e se alguém realmente quiser fazer DoS você, eles têm outras maneiras de qualquer maneira (por exemplo, baixando páginas de você).
nh2
1
@ManishSapkal Você provavelmente deve abrir uma nova pergunta para isso, ela não se encaixa bem nos comentários.
nh2
15

socket.disconnect() pode ser usado apenas no lado do cliente, não no lado do servidor.

Client.emit('disconnect')dispara o evento de desconexão no servidor, mas não desconecta efetivamente o cliente. O cliente não está ciente da desconexão.

Portanto, a questão permanece: como forçar um cliente a se desconectar do servidor?

Fabien
fonte
1
Você não precisa Client.emit('disconnect')mais chamar manualmente com as versões recentes de socket.io, agora existe um servidor socket.disconnect()(veja minha resposta).
nh2 de
5
Devido a atualizações recentes, sua resposta está incorreta agora, portanto, o -1.
corazza
Concordo, essa resposta não é mais válida, pois agora o também socket.disconnect()pode ser usado no lado do servidor.
Vassilis Barzokas
@VassilisBarzokas E se eu quiser um retorno de chamada e passar alguns parâmetros para o retorno de chamada depois que a disconnect()função for concluída?
newguy
crie um conjunto combinado de mensagens em que uma parte informe à outra parte que deseja se desconectar, faça o que você precisa fazer e, em seguida, desconecte-se de fato.
Mike 'Pomax' Kamermans
8

Alguma razão pela qual você não pode fazer com que o servidor emita uma mensagem ao cliente que o faça chamar a função de desconexão?

No cliente:

socket.emit('forceDisconnect');

No servidor:

socket.on('forceDisconnect', function(){
    socket.disconnect();
});
quahada
fonte
7
Porque o código do lado do cliente nunca pode funcionar exatamente como você deseja. Os usuários podem modificá-lo facilmente.
Kaustubh Karkare
4

Assumindo o soquete nomeado do seu soquete, use:

socket.disconnect()
Erik
fonte
2
Infelizmente, isso não funciona. Estou tentando fechar a conexão com um cliente específico do lado do servidor.
Daniel Kenney
4

Para quem encontrou isso no google - existe uma solução para isso agora:

Socket.disconnect()chuta o cliente (lado do servidor). Sem chance para o cliente ficar conectado :)

Sascha Gehlich
fonte
Como faço para localizar o soquete do usuário que está desconectado do servidor?
Manish Sapkal de
Manish: Ouça o disconnectevento do soquete para descobrir se ele foi desconectado. Também pode ser o closeevento, não tenho certeza. Consulte a documentação do socket.io para obter mais informações sobre isso.
Sascha Gehlich
3

No meu caso, eu queria derrubar a conexão subjacente, caso em que tive que ligar, socket.disconnect(true)como você pode ver, é necessário da fonte aqui

Duncan
fonte
2

client._onDisconnect() Deveria trabalhar

Emmerman
fonte
1
Isso funciona perfeitamente .. Eu mantenho meu próprio mapeamento para clientes .. usando esse mapeamento ... facilmente desconectando clientes ..
saúde
1

Socket.io usa o padrão EventEmitter para desconectar / conectar / verificar os batimentos cardíacos para que você possa fazer isso. Client.emit('disconnect');

Anthony Wlodarski
fonte
1

Isso não funcionou para mim:

`socket.disconnect()` 

Isso funcionou para mim:

socket.disconnect(true)

A transferência truefechará a conexão subjacente com o cliente e não apenas o namespace que o cliente está conectado à documentação do Socket IO .


Um exemplo de caso de uso: o cliente se conectou ao servidor de soquete da web com token de acesso inválido (token de acesso entregue ao servidor de soquete da web com parâmetros de conexão). O servidor de soquete da Web notifica o cliente de que fechará a conexão por causa de seu token de acesso inválido:

// (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
fonte
0

Estou usando client.emit('disconnect')+ client.removeAllListeners()para cliente conectado para ignorar todos os eventos após desconectar

homem do céu
fonte
0

Estou usando no lado do cliente socket.disconnect();

client.emit('disconnect') didnt work for me
Yonia
fonte
0

usar :

socket.Disconnect () // ok

não use :

socket.disconnect ()

m-tech
fonte
0

Você pode fazer socket = undefined apagar qual soquete você conectou. Então quando quiser conectar faça socket (url)

Então vai ficar assim

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

let socket;

// Connect to server
socket = socketClient(url)

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

Adicione novas conexões de soquete a uma matriz e, quando quiser fechar todas, faça um loop através delas e desconecte. (lado do servidor)

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
fonte