很简单的问题。 我建立使用作为的NodeJS我的后端实时的比赛,我想知道是否有任何信息,请访问哪一个更可靠,哪一个更有效? 我大量使用Redis的双方和整个Socket.io我的代码。 所以,我想知道我是否应该利用Socket.io的房间或者我会关闭使用Redis的更好的发布-订阅 ?
更新:刚刚意识到有为什么您可能希望使用Redis的发布/订阅了socket.io房间一个很重要的原因。 随着当你发布到听众Socket.io房间,(浏览器)客户端收到消息,与Redis的它实际上是(Redis的〜在服务器上)的客户谁收到的消息。 出于这个原因,如果你想告知的信息,具体到每一个客户端的所有(服务器)客户端,并传递到浏览器客户端之前,也许做一些处理,你最好使用Redis的。 使用Redis的你可以只火了一个事件来生成每个用户的个人数据,其中与socket.io你必须真正生成所有的用户同时独特的数据,然后依次通过他们,并把他们自己的个人数据,这几乎违背了房间,至少对我的目的。
不幸的是,我的目的,我坚持Redis的现在。
更新2:截止开发了一个插件,只使用2 Redis的连接,但仍然允许个别客户端处理,请参阅下面回答....
Redis的发布/订阅是巨大的情况下,所有的客户都Redis的直接访问。 如果有多个节点服务器,一个可以把一个消息给其他人。
但是,如果你也有客户在浏览器中,你需要的东西都可以从服务器将数据推送到客户端,在这种情况下,socket.io是伟大的。
现在,如果你使用socket.io与Redis的商店,socket.io将使用Redis的发布/订阅引擎盖下传播服务器之间的邮件,服务器将消息传播到客户端。
因此,使用与socket.io与Redis的商店配置socket.io房间可能是最简单的为您服务。
我最后写一个节点插件,以便为众多的发布 - 订阅客户端,但只需要2个Redis的连接,而不是每一个socketio连接上一个新的,它应该在一般的工作,想出别人可能会觉得使用它。
此代码假设你有socket.io运行和设置,基本在这个例子中的任何数量的socket.io的客户端可以连接,它总是会仍然只使用2个Redis的连接,但所有客户端都可以订阅自己的渠道。 在这个例子中,所有的客户端收到一条消息,“甜蜜的消息!” 10秒后。
例如用socket.io(利用redis的发布 - 订阅):
var
RPubSubFactory = require('rpss.js');
var
redOne = redis.createClient(port, host),
redTwo = redis.createClient(port, host);
var pSCFactory = new RPubSubFactory(redOne);
io.sockets.on('connection', function(socket){
var cps = pSCFactory.createClient();
cps.onMessage(function(channel, message){
socket.emit('message', message);
});
io.sockets.on('disconnect', function(socket){
// Dont actually need to unsub, because end() will cleanup all subs,
// but if you need to sometime during the connection lifetime, you can.
cps.unsubscribe('cool_channel');
cps.end();
});
cps.subscribe('cool_channel')
});
setTimeout(function(){
redTwo.publish('cool_channel', 'sweet message!');
},10000);
实际插件代码:
var RPubSubFactory = function(){
var
len,indx,tarr;
var
dbcom = false,
rPubSubIdCounter = 1,
clientLookup = {},
globalSubscriptions = {};
// public
this.createClient = function()
{
return new RPubSupClient();
}
// private
var constructor = function(tdbcom)
{
dbcom = tdbcom;
dbcom.on("message", incommingMessage);
}
var incommingMessage = function(rawchannel, strMessage)
{
len = globalSubscriptions[rawchannel].length;
for(var i=0;i<len;i++){
//console.log(globalSubscriptions[rawchannel][i]+' incomming on channel '+rawchannel);
clientLookup[globalSubscriptions[rawchannel][i]]._incommingMessage(rawchannel, strMessage);
}
}
// class
var RPubSupClient = function()
{
var
id = -1,
localSubscriptions = [];
this.id = -1;
this._incommingMessage = function(){};
this.subscribe = function(channel)
{
//console.log('client '+id+' subscribing to '+channel);
if(!(channel in globalSubscriptions)){
globalSubscriptions[channel] = [id];
dbcom.subscribe(channel);
}
else if(globalSubscriptions[channel].indexOf(id) == -1){
globalSubscriptions[channel].push(id);
}
if(localSubscriptions.indexOf(channel) == -1){
localSubscriptions.push(channel);
}
}
this.unsubscribe = function(channel)
{
//console.log('client '+id+' unsubscribing to '+channel);
if(channel in globalSubscriptions)
{
indx = globalSubscriptions[channel].indexOf(id);
if(indx != -1){
globalSubscriptions[channel].splice(indx, 1);
if(globalSubscriptions[channel].length == 0){
delete globalSubscriptions[channel];
dbcom.unsubscribe(channel);
}
}
}
indx = localSubscriptions.indexOf(channel);
if(indx != -1){
localSubscriptions.splice(indx, 1);
}
}
this.onMessage = function(msgFn)
{
this._incommingMessage = msgFn;
}
this.end = function()
{
//console.log('end client id = '+id+' closing subscriptions='+localSubscriptions.join(','));
tarr = localSubscriptions.slice(0);
len = tarr.length;
for(var i=0;i<len;i++){
this.unsubscribe(tarr[i]);
}
localSubscriptions = [];
delete clientLookup[id];
}
var constructor = function(){
this.id = id = rPubSubIdCounter++;
clientLookup[id] = this;
//console.log('new client id = '+id);
}
constructor.apply(this, arguments);
}
constructor.apply(this, arguments);
};
module.exports = RPubSubFactory;
我搞乱身边,并试图尽可能多的,因为我可以提高效率,但做一些不同的速度测试之后,我得出的结论,这是最快的,我能得到它。
要获得的最新版本: https://github.com/Jezternz/node-redis-pubsub