2013-04-23 119 views
1

特定的人我有socket.io,我用它來選擇和加載不同的外部模塊實時(我稱之爲「活動」)的Node.js應用。刪除所有事件監聽器,除了在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. 
    } 
} 

因此,例如在這個例子,如果我從改變對其他一些活動,我希望能夠爲所有客戶端刪除「act1」和「act2」的偵聽器,而不刪除「event1」,「event2」和「changeActivity」的偵聽器。

有關如何完成此任何想法?

+0

您可以(a)通過監聽'newListener'事件來保存這些事件名稱的列表,或者可以(b)使用'emitter.listeners()'獲取想要保留的事件的偵聽器'對於想要保留的事件,清除其他所有事件並重新附加它們(從未嘗試過,可能有副作用)。 – Wrikken 2013-04-23 21:46:53

+0

@Wrikken,似乎沒有newListener事件,或者至少我在文檔中找不到它。有任何鏈接?對於第二種選擇,我想我需要在服務器中知道模塊中事件的名稱,導致不希望的耦合。 – Sam 2013-04-24 17:29:26

+1

那麼,[這個網頁上說]有(http://nodejs.org/api/events.html#events_event_newlistener)。根據[本頁](http://nodejs.org/changelog.html),它自2009.08.27版本0.1.7開始一直存在。 – Wrikken 2013-04-24 17:34:37

回答

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 2013-04-24 17:30:43

+0

另外,我認爲你的重構工作會很好,但是對我來說不是這樣,因爲我想爲所有n個客戶端只有一個模塊實例。 – Sam 2013-04-24 17:32:13

+1

服務器只需要使用綁定和解除綁定方法,就像一個接口一樣。我更改了用法以共享活動實例。我可能會誤解你的意圖。你能舉一些socket.io代碼的例子嗎? – 2013-04-28 15:28:50