套接字.如何删除onConnect上注册的猫鼬事件侦听器
Socket.io Leak - How do I remove this mongoose event listener that is registered onConnect?
当用户通过socket.io连接时,我有以下订阅:
socket.on('subscribe', function(room) {
console.log('joining room', room.id);
socket.join(room.id);
socket.roomName = room.id;
// Insert sockets below
require('../api/item/item.socket').register(socket);
});
"项目。"Socket"代码为数据库事件(保存、删除等)附加mongoose事件处理程序,并在事件发生时发出Socket消息。下面是代码:
var Item = require('./it');
exports.register = function(socket) {
Item.schema.post('save', function (doc) {
console.log("hit save message");
onSave(socket, doc);
});
Item.schema.post('update', function (doc) {
console.log("hit update message");
onSave(socket, doc);
});
Item.schema.post('remove', function (doc) {
onRemove(socket, doc);
});
};
function onSave(socket, doc, cb) {
socket.emit(doc._id + ':item:save', doc);
}
function onRemove(socket, doc, cb) {
socket.emit(doc._id + ':item:remove', doc);
}
当客户端断开连接时,执行以下代码:
function onDisconnect(socket) {
console.log('disconnected: ' + socket.roomName);
socket.leave(socket.roomName);
socket.removeAllListeners("subscribe");
}
我遇到的基本问题是,如果用户连接到get那个项目。套接字猫鼬处理程序发送关于模型更改的更新。当它们断开连接(重新加载页面,离开,回来,等等),即使处理程序永远不会消失。例如,我更改了"item",如果我重新加载页面10次,我将得到10个"点击保存"消息。
理想情况下,当客户端离开页面时,该猫鼬处理程序将被销毁,因此它不会试图向任何人发送消息。
编辑:我很清楚,这是一个事件处理程序泄漏。基本上我需要做一些事情来销毁disconnect的handler。我需要以某种方式创建一个对require('../api/item/item.socket').register(socket);
的引用,然后断开连接,取消注册,但我不知道如何正确地使用猫鼬模型和我设置它的方式。
function onDisconnect(socket) { console.log('disconnected: ' + socket.roomName); socket.leave(socket.roomName); socket.removeAllListeners("subscribe"); //destroy handler here }
一个可能的解决方案如下。您可以维护在"item.socket"中连接的套接字集合。"项。然后将导出函数,以便在此集合中添加和删除套接字。所以,你会"require" item。在您的代码中使用一次套接字,然后在建立连接时使用套接字调用其add方法。类似地,当它断开连接时,您可以使用套接字调用它的remove方法。项中的猫鼬事件处理程序。套接字应遍历套接字集合,并在适用时发出消息。如果您希望以加载多个实例的方式"要求"该模块,则不妨将套接字集合附加到全局命名空间。
谢谢你的见解,有时候你只是盯着一个问题太久,然后意识到答案是直截了当的。我基本上按照你说的做了,只注册了一次item.socket
。然而,我们没有保留一个套接字列表,而是使用socket.io
方式将消息发送到正确的套接字,代码如下:
'use strict';
var Item = require('./item.model');
var log4js = require('log4js');
var logger = log4js.getLogger();
exports.register = function(socketio) {
Item.schema.post('save', function (doc) {
logger.debug("hit save message " + doc._id);
onSave(socketio, doc);
});
Item.schema.post('update', function (doc) {
logger.debug("hit update message");
onSave(socketio, doc);
});
Item.schema.post('remove', function (doc) {
onRemove(socketio, doc);
});
};
function onSave(socketio, doc, cb) {
socketio.sockets.in(doc._id).emit(doc._id + ':item:save', doc);
}
function onRemove(socketio, doc, cb) {
socketio.sockets.in(doc._id).emit(doc._id + ':item:remove', doc);
}
其中doc._id
为客户端订阅时加入的房间。泄漏固定! !谢谢:-)
- Highslide(iframe的侦听器)
- 如何在for循环中添加事件侦听器
- 选项卡侦听器未被来自后台脚本的消息激活
- 在Firefox插件中注册控制台服务侦听器
- 注册用于捕获阶段的事件侦听器在冒泡之前未触发 - 为什么
- 在角度 api 中$watch返回一个取消注册函数,用于此侦听器取消注册的含义是什么
- jQuery 注册 2 个键事件侦听器时遇到问题
- 在javascript中注册事件侦听器的最有效方法是什么
- 注册窗口甚至侦听器
- Javascript 注册事件侦听器
- 在 Web 辅助角色中注册事件侦听器
- 初始化Angular应用程序后立即注册事件侦听器
- 注册多个事件侦听器,即使我'm正在使用removeEventListener
- javascript:注册第二个事件侦听器.如何防止某些事件发生
- 事件侦听器不会在某些类型的元素上注册单击事件
- 我可以通过'this'作为将事件侦听器注册到local-DOM子节点时的参数
- 如何在Portlet中注册IcePush侦听器
- 套接字.如何删除onConnect上注册的猫鼬事件侦听器
- 如何在d3中将多个外部侦听器注册到同一选择
- 为什么事件侦听器只注册在for循环中创建的最后一个元素?