使用socket.io和nodejs强制客户端与服务器断开连接


117

有什么方法可以通过SocketIO断开客户端的连接并从字面上关闭连接吗?因此,如果有人连接到我的服务器,而我想关闭他们与服务器之间的连接,我该怎么做呢?

Answers:


145

编辑:这现在是可能的

现在,您只需socket.disconnect()在服务器端调用即可

我的原始答案:

这还不可能。

如果您也需要它,请对此问题进行投票/评论。


因此,我这样做了,它确实迫使客户端断开连接,但不幸的是,客户端似乎只是立即重新连接。我是在误解发生了什么,还是预期的行为?
kybernetikos

@kybernetikos是的,我希望如此-客户毕竟可以选择自己做些什么。通常,您想踢出当前连接的另一端,例如由于auth超时-在此之后重新连接甚至可能是可取的。
nh2 2013年

那么,您是否知道以任何方式告诉客户“离开,我的意思是真的”?我正在从确定客户端表现不佳而不希望他们用完我服务器上的资源的角度考虑。
kybernetikos

@kybernetikos不,您通常不能这样做。如果您正在对客户端进行编程,则当然可以实现所需的任何逻辑,例如,阻止其重新连接。如果不是,则必须反复踢用户,或者如果确实有必要,则采用标准的阻止技术;实施的级别越低(例如iptables),您将节省更多的资源。但是,在大多数情况下,只需踢一下客户端就足够了,因为socketio不能快速连接客户端,并且如果有人真的想对您进行DoS,反正他们还有其他方法(例如,从您下载页面)。
nh2

1
@ManishSapkal您可能应该为此提出一个新问题,它不适合评论。
nh2 2014年

15

socket.disconnect() 只能在客户端使用,不能在服务器端使用。

Client.emit('disconnect')触发服务器上的断开连接事件,但不能有效断开客户端连接。客户端不知道断开连接。

因此,问题仍然存在:如何强制客户端从服务器端断开连接?


1
您不必Client.emit('disconnect')再使用最新的socket.io版本进行手动调用,现在有了服务器端socket.disconnect()(请参阅我的回答)。
nh2 2012年

5
由于最近的更新,您的答案现在不正确,因此为-1。
corazza 2012年

我同意,此答案不再有效,因为现在socket.disconnect()可以在服务器端使用。
Vassilis Barzokas '16

@VassilisBarzokas如果我想要回调并在disconnect()函数完成后将一些参数传递给回调该怎么办?
newguy

创建一组同意的消息,其中一方通知另一方他们希望断开连接,然后执行您需要做的事情,然后实际断开连接。
Mike'Pomax'Kamermans

8

您为什么不能让服务器向客户端发送一条消息,使其调用断开功能?

在客户端上:

socket.emit('forceDisconnect');

在服务器上:

socket.on('forceDisconnect', function(){
    socket.disconnect();
});

7
因为永远不能依赖客户端代码来完全按照您想要的方式运行。用户可以轻松地对其进行修改。
Kaustubh Karkare 2013年

4

假设您的套接字名为套接字,请使用:

socket.disconnect()

2
不幸的是,这不起作用。我正在尝试从服务器端关闭到特定客户端的连接。
Daniel Kenney

4

对于那些在Google上发现此问题的人-现在有解决方案:

Socket.disconnect()踢客户端(服务器端)。客户没有机会保持联系:)


如何找到服务器上断开连接的用户的套接字?
Manish Sapkal 2014年

Manish:侦听套接字的disconnect事件,以了解其是否已断开连接。我也close不太确定,这也可能是事件。有关此的更多信息,请参见socket.io的文档。
Sascha Gehlich 2014年


3

在我的情况下,我想拆除基础连接,在这种情况下,我必须调用它,socket.disconnect(true)如您所见,需要从此处获取源代码


2

client._onDisconnect() 应该管用


1
完美运行..我维护自己对客户端的映射..使用该映射...轻松断开客户端的连接..欢呼声
Arenstar 2011年


1

这对我不起作用

`socket.disconnect()` 

确实为我工作

socket.disconnect(true)

移交true将关闭与客户端的底层连接,而不仅仅是客户端与Socket IO文档连接的名称空间。


一个示例用例:客户端确实使用无效的访问令牌连接到了Web套接字服务器(使用连接参数将访问令牌移交给了Web套接字服务器)。Web套接字服务器由于其无效的访问令牌通知客户端它将要关闭连接:

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

我为连接的客户端使用client.emit('disconnect')+ client.removeAllListeners()来断开连接后忽略所有事件


0

我在客户端使用 socket.disconnect();

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

0

用 :

socket.Disconnect()//确定

不使用 :

socket.disconnect()


0

您可以socket = undefined擦除已连接的插座。所以当想连接时做socket(url)

所以看起来像这样

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

let socket;

// Connect to server
socket = socketClient(url)

// When want to disconnect
socket = undefined;

-1

将新的套接字连接添加到阵列,然后在要关闭所有套接字连接时-遍历它们并断开连接。(服务器端)

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();                      
    });    
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.