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

时间:2012-08-30 18:32:24

标签: jquery node.js socket.io listener

我使用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 个答案:

答案 0 :(得分:6)

我知道你已经解决了这个问题,但无论如何我都会回答,所以人们都知道发生了什么。

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

当你定义一个eventListener(即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)虽然在createRoom事件的回调函数中定义了roomJoin和messageReceived事件,但它们仍然在webSocket对象的同一个实例上运行。所以你最终得到一个类似于:

的侦听器对象
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');
});