Javascript 除去Socket.io中的特定事件侦听器之外的所有事件侦听器

Javascript 除去Socket.io中的特定事件侦听器之外的所有事件侦听器,javascript,node.js,socket.io,Javascript,Node.js,Socket.io,我有一个node.js应用程序和socket.io,我用它来实时选择和加载不同的外部模块(我称之为“活动”) 因为每个模块都将自己的事件绑定到套接字,所以当我从一个模块切换到另一个模块时,我希望能够从套接字中删除前一个模块添加的所有事件侦听器 我会使用,但这也会删除我在服务器中定义的事件,这是我不想要的 下面是我的代码的样子: app.js // Boilerplate and some other code var currentActivity; io.sockets.on('connec

我有一个node.js应用程序和socket.io,我用它来实时选择和加载不同的外部模块(我称之为“活动”)

因为每个模块都将自己的事件绑定到套接字,所以当我从一个模块切换到另一个模块时,我希望能够从套接字中删除前一个模块添加的所有事件侦听器

我会使用,但这也会删除我在服务器中定义的事件,这是我不想要的

下面是我的代码的样子:

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
    });
})
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.
    }
}
下面是一个示例活动

someActivity.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
    });
})
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.
    }
}
例如,在本例中,如果我从
someActivity.js
更改为其他活动,我希望能够为所有客户端删除“act1”和“act2”的侦听器,而不删除“event1”、“event2”和“changeActivity”的侦听器


关于如何实现这一点,有什么想法吗?

我会在每个模块中创建一个名为取消绑定的方法,该方法将删除由绑定函数添加的所有侦听器:

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();
});

我将在每个模块中创建一个名为unbind的方法,该方法删除bind函数添加的所有侦听器:

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();
});

您可以(a)通过侦听
newListener
事件来保留这些事件名称的列表,或者(b)为您希望与
emitter.listeners()一起保留的事件获取侦听器。对于您希望保留的事件,清除所有其他事件,然后重新附加它们(从未尝试过,可能会有副作用)。@Wrikken,似乎没有newListener事件,或者至少我在文档中找不到它。有联系吗?对于第二个选项,我想我需要在服务器中知道模块中事件的名称,这会导致不希望的耦合。根据它自2009.08.27版本0.1.7以来一直存在的说法。对不起,我正在查看Socket.io文档。谢谢;)您可以(a)通过侦听
newListener
事件来保留这些事件名称的列表,或者(b)为您希望与
emitter.listeners()一起保留的事件获取侦听器。对于您希望保留的事件,清除所有其他事件,然后重新附加它们(从未尝试过,可能会有副作用)。@Wrikken,似乎没有newListener事件,或者至少我在文档中找不到它。有联系吗?对于第二个选项,我想我需要在服务器中知道模块中事件的名称,这会导致不希望的耦合。根据它自2009.08.27版本0.1.7以来一直存在的说法。对不起,我正在查看Socket.io文档。谢谢;)谢谢我第一个想法是想到了一些东西,但这对我来说似乎有点重复。另外,这取决于模块的实现,您认为有没有另一种方法可以解决这个问题,服务器可以控制解除绑定,而不知道模块中事件的名称?另外,我认为您的重构工作会很好,但我的情况不是这样,因为我只想为所有n个客户端提供一个模块实例。服务器只需要使用绑定和取消绑定方法,就像一个接口一样。我更改了用法以共享活动实例。我可能误解了你的意图。你能展示一些示例socket.io代码吗?谢谢。我第一个想法是想到了一些东西,但这对我来说似乎有点重复。另外,这取决于模块的实现,您认为有没有另一种方法可以解决这个问题,服务器可以控制解除绑定,而不知道模块中事件的名称?另外,我认为您的重构工作会很好,但我的情况不是这样,因为我只想为所有n个客户端提供一个模块实例。服务器只需要使用绑定和取消绑定方法,就像一个接口一样。我更改了用法以共享活动实例。我可能误解了你的意图。您可以展示一些示例socket.io代码吗?