递归删除多个 socket.io 监听器

Posted

技术标签:

【中文标题】递归删除多个 socket.io 监听器【英文标题】:Remove multiple socket.io listeners recursively 【发布时间】:2012-08-25 13:24:35 【问题描述】:

我正在使用 node.js 和 socket.io 编写一个应用程序,用户可以在其中在个人聊天室中相互交谈。每个人都可以有多个打开的聊天室。当用户想要退出聊天室时,系统必须移除该聊天室的所有套接字监听器。

websocket.on('createRoom', function(roomID) 
    ...
    var room = generateRoom();
    ...

    // Leaving room
    $('#exitButton').on('click', function() 
        // Removes
        websocket.removeAllListeners('createRoom');
    );

    // User joins the room
    websocket.on('main/roomJoin/'+roomID, function(username) 
        alert(username + ' has joined the room');
    );

    ...

    websocket.on('chat/messageReceived/'+roomID, function(message) 
        room.printMessage(message);
    );
);

问题是 removeAllListeners 不会删除内部监听器,所以如果另一个用户在另一个用户退出后进入房间,他会收到警报。

另一种方法是将听众放在外面,但管理多个房间比较困难。

谢谢。

【问题讨论】:

我终于手动删除了每个监听器。 如果您已经解决了问题,请发布您的解决方法作为答案。 【参考方案1】:

我知道你已经解决了这个问题,但我还是会回答,以便人们知道发生了什么。

1) removeAllListeners() 仅删除相关事件的回调数组;它根本不会影响任何其他事件。

当您定义一个事件监听器(即 on('xyz', function())时,您将回调函数附加到由提供的事件名称索引的数组中。该数组是相关对象的成员,在您的情况下,“webSocket”对象。webSocket.on("createRoom", function()) 将函数添加到类似于

的对象
webSocket.listeners = 
    "createRoom: [ function ],
    "someOtherEvent": [ function, function, function ]

webSocket.removeAllListeners('createRoom') 将简单地从对象中删除 createRoom 键及其关联值,而不影响任何其他事件:

webSocket.listeners =  "someOtherEvent": [ function, function, function ] 

2) 虽然 roomJoin 和 messageReceived 事件是在 createRoom 事件的回调函数中定义的,但它们仍然在 webSocket 对象的同一个实例上运行。因此,您最终会得到一个类似于以下内容的 listeners 对象:

webSocket.listeners = 
    "createRoom: [ function ],
    "main/roomJoin: [ function ],
    "chat/messageReceived": [ function ]

结合上面第 1 点的信息,webSocket.removeAllListeners('createRoom') 将产生以下结果:

webSocket.listeners = 
    "main/roomJoin: [ function ],
    "chat/messageReceived": [ function ]

仅仅因为这两个事件是在另一个事件的回调中定义的,并不意味着它们无论如何都与那个“父”事件相关联。正如您现在所知道的,删除这些侦听器的唯一方法是显式删除它们:

$('#exitButton').on('click', function() 
    // Removes
    websocket.removeAllListeners('createRoom');
    websocket.removeAllListeners('main/roomJoin');
    websocket.removeAllListeners('chat/messageReceived');
);

【讨论】:

以上是关于递归删除多个 socket.io 监听器的主要内容,如果未能解决你的问题,请参考以下文章

Socket.io 执行后删除监听器

如何防止多个 Socket.io 事件监听器

从 socket.io 中删除特定的类方法监听器

removeAllListeners() 根本不删除侦听器? (Socket.IO)

如何删除 io.on('connection') 监听器?

为啥没有调用android端的socket.io监听器?