发布/订阅
问题描述:
我试图在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);
}
}
}
答
你可以使用一个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);
}
}
非常感谢!我只是不明白'channels [channel] .emit('message',channel,data);'你为什么要在这一行传递'channel'?因此,对于订阅,我需要将引用传递给我的回调,当我们发布到某人订阅的频道时,我们会发出订阅中提供的回调函数,对吗? – user385729 2015-02-06 02:55:05
我收录了'channel',因为你的例子包含'channel'作为回调参数之一('sub.on(“message”,function(channel,data){...})')。这不是真的有必要。 – Ben 2015-02-06 18:43:39
'EventEmitter'记录你的回调。所以,你所要做的就是告诉'EventEmitter'在有人发出'message'时调用回调函数。解决这个问题的另一种方法是使用一个'EventEmitter'命名空间来处理事件。例如事件名称可能是'channel +':message''。 – Ben 2015-02-06 18:46:03