Jos*_* Mc 29 publish-subscribe redis node.js socket.io
非常简单的问题.我正在使用nodejs作为我的后端构建一个实时游戏,我想知道是否有任何信息可用哪个更可靠哪个更有效?我在整个代码中大量使用Redis和Socket.io.所以我想知道我是否应该使用Socket.io的房间,或者我最好使用redis'pub -sub?
更新: 刚刚意识到有一个非常重要的原因,你可能想在socket.io房间使用redis pub/sub.使用Socket.io房间发布给监听器时,(浏览器)客户端收到消息,redis实际上是(redis~on on server)客户端收到消息.因此,如果您想要通知所有(服务器)客户端特定于每个客户端的信息,并且可能在传递给浏览器客户端之前进行一些处理,那么最好使用redis.使用redis你可以发起一个事件来生成每个用户的个人数据,就像socket.io一样,你必须一次实际生成所有用户的唯一数据,然后遍历它们并发送它们各自的数据,这几乎击败了房间的目的,至少对我而言.
不幸的是,就我的目的而言,我现在仍然坚持使用redis.
更新2:结束开发插件只使用2个redis连接,但仍然允许单独的客户端处理,请参阅下面的答案....
Pas*_*cle 35
如果所有客户都可以直接访问redis,Redis pub/sub非常棒.如果您有多个节点服务器,则可以将消息推送给其他节点服务器.
但是,如果您在浏览器中也有客户端,则需要其他东西将数据从服务器推送到客户端,在这种情况下,socket.io非常棒.
现在,如果您将socket.io与Redis存储一起使用,socket.io将使用Redis pub/sub在服务器之间传播消息,服务器将消息传播到客户端.
因此,使用带有使用Redis存储配置的socket.io的socket.io房间可能是最简单的.
我最终编写了一个节点插件,允许许多pub-sub客户端,但在每个socketio连接上只需要2个redis连接而不是新的连接,它应该可以正常工作,想象其他人可能会发现它的用途.
这段代码假设你有socket.io运行和设置,基本上在这个例子中任何数量的socket.io客户端都可以连接,它总是仍然只使用2个redis连接,但是所有客户端都可以订阅自己的通道.在此示例中,所有客户端都会收到消息"甜蜜的消息!" 10秒后
socket.io示例(使用redis pub-sub):
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);
Run Code Online (Sandbox Code Playgroud)
实际插件代码:
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;
Run Code Online (Sandbox Code Playgroud)
我尽可能地试图提高效率,但在做了一些不同的速度测试后,我得出结论,这是我能得到的最快速度.
对于最新版本:https://github.com/Jezternz/node-redis-pubsub