2

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?

4
  • You could (a) keep a list of those event names by listening to the newListener event, or pssibly (b) get the listeners for the events you want to keep with emitter.listeners() for the events you want to keep, clear all else, and reattach them (never tried it, might have side effects). Commented Apr 23, 2013 at 21:46
  • @Wrikken, it seems there is no newListener event, or at least I can't find it in the docs. Got any link? For your second option, I think I would need to know in the server the name of the events in the module, causing an undesired coupling. Commented Apr 24, 2013 at 17:29
  • 1
    Well, this page says there is. According to this page it's been there since 2009.08.27 Version 0.1.7. Commented Apr 24, 2013 at 17:34
  • 1
    Sorry, I was looking in the Socket.io documentation. Thanks ;) Commented Apr 24, 2013 at 17:37

1 Answer 1

1

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(); }); 
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks. I had thought of something as the first idea, but that seemed a little bit repetitive for me. Also, it depends on the module implementation, do you think there is another way to solve this where the server has control of the unbinding, without knowing the name of the events in the module?
Also, I think your refactor would work quite good, but not in my case since I want to have only one instance of the module for all of the n clients.
The server would only need to use the bind and unbind methods, like an interface. I changed the usage to share the activity instances. I may be misunderstanding your intention. Can you show some example socket.io code?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.