2013-04-23 149 views
1

特定的人我有socket.io,我用它来选择和加载不同的外部模块实时(我称之为“活动”)的Node.js应用。删除所有事件监听器,除了在Socket.io

由于每个模块结合它自己的事件到插座,当我改变从一个模块到另一个我希望能够从我的插座删除所有的事件监听器,以前的模块添加。

我会用emitter.removeAllListeners(),但也将消除我的服务器,我不想定义的事件。

这里是我的代码看起来是这样的:

app.js

// Boilerplate and some other code 

var currentActivity; 
io.sockets.on('connection', function(client){ 

    client.on('event1', callback1); 
    client.on('event2', callback2); 

    client.on('changeActivity', function(activityPath){ 
     var Activity = require(activityPath); 
     currentActivity = new Activity(); 

     // Here I'd like some loop over all clients and: 
     // 1.- Remove all event listeners added by the previous activity 
     // 2.- Call currentActivity.bind(aClient) for each client 
    }); 
}) 

一个例子活动会像下面

someActivity.js

module.exports = function(){ 

    // some logic and/or attributes 

    var bind = function(client){ 

     client.on('act1' , function(params1){ // some logic 
     }); 
     client.on('act2' , function(params2){ // some logic 
     }); 
     // etc. 
    } 
} 

因此,例如在这个例子,如果我从改变对其他一些活动,我希望能够为所有客户端删除“act1”和“act2”的侦听器,而不删除“event1”,“event2”和“changeActivity”的侦听器。

有关如何完成此任何想法?

+0

您可以(a)通过监听'newListener'事件来保存这些事件名称的列表,或者可以(b)使用'emitter.listeners()'获取想要保留的事件的侦听器'对于想要保留的事件,清除其他所有事件并重新附加它们(从未尝试过,可能有副作用)。 – Wrikken 2013-04-23 21:46:53

+0

@Wrikken,似乎没有newListener事件,或者至少我在文档中找不到它。有任何链接?对于第二种选择,我想我需要在服务器中知道模块中事件的名称,导致不希望的耦合。 – Sam 2013-04-24 17:29:26

+1

那么,[这个网页上说]有(http://nodejs.org/api/events.html#events_event_newlistener)。根据[本页](http://nodejs.org/changelog.html),它自2009.08.27版本0.1.7开始一直存在。 – Wrikken 2013-04-24 17:34:37

回答

1

我会叫解除绑定,去除全部由绑定功能添加了听众的每个模块中创建一个方法:

var fun1 = function(params1){ // some logic };  
var fun2 = function(params2){ // some logic }; 

module.exports = function(){  
    // some logic and/or attributes  
    var bind = function(client){  
     client.on('act1' , fun1); 
     client.on('act2' , fun2); 
    } 

    var unbind = function(client){ 
     client.removeEventListener('act1',fun1); 
     client.removeEventListener('act2',fun2); 
    }; 
}; 

如果您需要在监听器访问客户,我会重构它的客户端传递给构造函数:

function MyModule(client){ 
    this.client = client; 
}; 
MyModule.prototype.fun1 = function(params1){ 
    //do something with this.client 
}; 
MyModule.prototype.fun2 = function(params2){ 
    //do something with this.client 
}; 
MyModule.prototype.bind = function(){ 
    this.client.on('act1' , this.fun1); 
    this.client.on('act2' , this.fun2); 
}; 
MyModule.prototype.unbind = function(){ 
    this.client.removeEventListener('act1' , this.fun1); 
    this.client.removeEventListener('act2' , this.fun2); 
}; 
module.exports = MyModule; 

然后你可以使用它像:

client.on('changeActivity', function(activityPath){ 
    var Activity = require(activityPath); 
    var currentActivity = activityCache[activityPath] || new Activity(client); //use the existing activity or create if needed 
    previousActivity.unbind(); 
    currentActivity.bind(); 
}); 
+0

谢谢。我想到了第一个想法,但对我来说这似乎有点重复。另外,它取决于模块的实现,你认为有另一种方法可以解决这个问题:服务器控制解除绑定,而不知道模块中事件的名称? – Sam 2013-04-24 17:30:43

+0

另外,我认为你的重构工作会很好,但是对我来说不是这样,因为我想为所有n个客户端只有一个模块实例。 – Sam 2013-04-24 17:32:13

+1

服务器只需要使用绑定和解除绑定方法,就像一个接口一样。我更改了用法以共享活动实例。我可能会误解你的意图。你能举一些socket.io代码的例子吗? – 2013-04-28 15:28:50