2015-02-05 179 views
0

我試圖在Node中實現發佈/訂閱模式,但沒有使用Redis。功能應該是一樣的;您可以發佈到頻道,訂閱頻道並在訂閱後收聽數據;這裏是Redis的功能:發佈/訂閱

pub.publish('channel1', myData1, function (err, data) {  
}); 


sub.subscribe('channel1', function (err, data) { 
}); 


sub.on("message", function (channel, data) { 
    //Now you are easily listening to data 
}); 

我曾嘗試以下,這可能不是在所有的好方法(我只是展示我的企圖!);我有自己的頻道對象,用於保存在向特定頻道發佈新數據時需要觸發的頻道和功能;所以你看到我正在爲頻道訂閱功能;但是,我不知道是否有任何方法可以像redis提供的數據一樣收聽數據!所以,請你幫我,如果因爲Redis的做我能做到同樣的方式,但eventEmitter或...

var events = require('events'); 
var emitter = new events.EventEmitter; 
var channels = {}; 
//channels ={"channelA": ["func1", "func2"], "channelB": []} 

//publish data to a channel and emits all of the functions which are registered for listening to the channel 
function publish(channel, data, callback) { 
    if (channels[channel] && channels[channel].length > 0) { 
     for (var i = 0; i < channels[channel].length; i++) { 
      emitter.emit(channels[channel][i], data); 
     } 
    } 
    callback(); 

} 

//subscribe a function to a channel 
function subscribe(channel, FuncName, next) { 
    if (!channels[channel]) { 
     channels[channel] = []; 
    } 
    channels[channel].push(FuncName); 
    next(); 
} 

//Subscribe a callback function from a channel 
function unsubscribe(channel, FuncName) { 
    if (channels[channel]) { 
     var indx = channels[channel].indexOf(FuncName); 
     if (indx != -1) { 
      channels[channel].splice(indx, 1); 
     } 
    } 
} 

回答

1

你可以使用一個EventEmitter每個通道。另外,您可能希望保存對回調的引用,而不是函數名稱字符串。

var events = require('events'); 
var channels = {}; 

//publish data to a channel and emits all of the functions which are registered for listening to the channel 
function publish(channel, data, callback) { 
    if (channels[channel]) { 
    channels[channel].emit('message', channel, data); 
    } 
    callback(); 
} 

//subscribe a function to a channel 
function subscribe(channel, fn, next) { 
    if (!channels[channel]) { 
    channels[channel] = new events.EventEmitter(); 
    } 
    channels[channel].addListener('message', fn); 
    next(); 
} 

//unsubscribe a callback function from a channel 
function unsubscribe(channel, fn) { 
    if (channels[channel]) { 
    channels[channel].removeListener('message', fn); 
    } 
} 
+0

非常感謝!我只是不明白'channels [channel] .emit('message',channel,data);'你爲什麼要在這一行傳遞'channel'?因此,對於訂閱,我需要將引用傳遞給我的回調,當我們發佈到某人訂閱的頻道時,我們會發出訂閱中提供的回調函數,對嗎? – user385729 2015-02-06 02:55:05

+1

我收錄了'channel',因爲你的例子包含'channel'作爲回調參數之一('sub.on(「message」,function(channel,data){...})')。這不是真的有必要。 – Ben 2015-02-06 18:43:39

+0

'EventEmitter'記錄你的回調。所以,你所要做的就是告訴'EventEmitter'在有人發出'message'時調用回調函數。解決這個問題的另一種方法是使用一個'EventEmitter'命名空間來處理事件。例如事件名稱可能是'channel +':message''。 – Ben 2015-02-06 18:46:03