Удалите несколько ретрансляторов socket.io

Я кодирую приложение с 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() удаляет только массив обратных вызовов для рассматриваемого события; это не влияет на какие-либо другие события вообще.

Когда вы определяете 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) Хотя события roomJoin и messageReceived были определены в функции обратного вызова события createRoom, они все еще работают в одном экземпляре объекта 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');
});

licensed under cc by-sa 3.0 with attribution.