2

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

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

我会使用emiter.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.
    }
}

因此,例如在本例中,如果我从someActivity.js其他活动更改,我希望能够为所有客户端删除“act1”和“act2”的侦听器,而不删除“event1”的侦听器,“ event2”和“changeActivity”。

关于如何做到这一点的任何想法?

4

1 回答 1

1

我将在每个模块中创建一个名为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();
});
于 2013-04-23T21:48:35.137 回答