2015-02-05 189 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