2013-04-23 2 views
1

У меня есть приложение node.js с socket.io, которое я использую для выбора и загрузки различных внешних модулей (которые я называю «действия») в режиме реального времени.Убрать все прослушиватели событий, кроме определенных в 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. 
    } 
} 

Так, например, в этот пример, если я перехожу от someActivity.js, я хотел бы удалить для всех клиентов слушателей «act1» и «act2», не удаляя их для «event1», «event2» и «changeActivity».

Любая идея о том, как это сделать?

+0

Вы могли бы (а) сохранить список этих имен событий, слушая 'newListener' события или pssibly (б) получить слушатель для событий, которые вы хотите сохранить с' emitter.listeners() ' для событий, которые вы хотите сохранить, очистить все остальное и повторно подключить их (никогда не пробовал, может иметь побочные эффекты). – Wrikken

+0

@Wrikken, похоже, нет события newListener или, по крайней мере, я не могу найти его в документах. У вас есть ссылка? Для вашего второго варианта, я думаю, мне нужно будет знать на сервере имя событий в модуле, вызывая нежелательную связь. – Sam

+1

Ну, [эта страница говорит, что есть] (http://nodejs.org/api/events.html#events_event_newlistener). Согласно [этой странице] (http://nodejs.org/changelog.html) он существует с 2009.08.27 Версия 0.1.7. – Wrikken

ответ

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

+0

Кроме того, я думаю, что ваш рефактор будет работать неплохо, но не в моем случае, так как я хочу иметь только один экземпляр модуля для всех n клиентов. – Sam

+1

Серверу необходимо будет использовать только методы bind и unbind, такие как интерфейс. Я изменил использование, чтобы разделить экземпляры активности. Возможно, я не понимаю ваше намерение.Вы можете показать пример кода socket.io? –