Reputation: 1232
I have node.js app with socket.io which I use to select and load different external modules (which I call "activities") in real time.
Since every module binds it's own events to the sockets, when I change from one module to another I want to be able to remove from my sockets all the event listeners that the previous module added.
I would use emitter.removeAllListeners(), but that would also remove the events I define in the server, which I do not want.
Here is how my code looks like:
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
});
})
An example activity would be something like the following
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.
}
}
So, for instance in this example, if I change from someActivity.js
to some other activity, I'd like to be able to remove for all clients the listeners for "act1" and "act2", without removing the ones for "event1", "event2" and "changeActivity".
Any idea on how to accomplish this?
Upvotes: 2
Views: 7012
Reputation: 14062
I would create a method in each module called unbind that removes all of the listeners added by the bind function:
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);
};
};
If you need access to the client in the listeners, I would refactor it to pass the client to the constructor:
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;
Then you can use it like:
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();
});
Upvotes: 1