我使用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没有移除内部侦听器,因此如果另一个用户在另一个用户退出后进入会议室,则会收到警报。
另一种方法是将听众放在外面,但管理多个房间更难。
感谢。
答案 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');
});