2012-04-13 65 views
14

我是redis pub/sub的新手。我在系统中有一个像IM一样的聊天工具。所以我想使用redis pub/sub。正如我已经检查过的样本,其中大部分是基于聊天室设计的。在我的系统中,我将有多个用户之间的聊天室,如何设计即时通讯系统的redis pub/sub?

A:B 
A:C 
D:C 
E:F 

因此,上面的行是房间。我已经实现了像下面的node.js服务器;

var store = redis.createClient(); 
var pub = redis.createClient(); 
io.sockets.on('connection', function (socket) { 
    var sub = redis.createClient(); 

    sub.on("message", function(pattern, data){ 
      data = JSON.parse(data); 
     socket.send(JSON.stringify({ type: "chat", key: pattern, nick: data.nickname, message: data.text })) 
     } 
    }); 

    socket.on('message', function (messageData) { 
     store.incr("messageNextId", function(e, messageId) { 
     var room = "" 
     var from = messageData.clientId > socket.nickname ? socket.nickname : messageData.clientId; 
     var to = messageData.clientId < socket.nickname ? socket.nickname : messageData.clientId; 
      room = from + ":" + to; 

     var message = { id: messageId, nickname: socket.nickname, text: messageData.text }; 
     store.rpush("rooms:" + room, JSON.stringify(message), function(e, r) { 
      pub.publish(room, JSON.stringify(message)) 
     }); 
    }); 
}); 

正如你可以看到我创建每个连接的新Redis的用户。在其他聊天室示例中,redis订户客户端在全球范围内创建。并且始终只存在三个连接并解决了他们的问题,因为当发布者发布消息时,所有连接的客户端都应该获得它。但我在这里有一个限制。我想打开两个用户之间的聊天会话,只有这些用户应该是订阅者。上面的代码正如我所愿,但我不知道redis是否可以为每个连接创建一个新的订阅者客户端。

很高兴听到您的建议。提前致谢。

回答

20

与往常一样,您需要为您自己的用例基准测试这样的事情 - 不可能提供一般性建议。您可能需要增加系统上或Redis用户的系统上打开文件的最大数量。当然,这也适用于运行Web服务器的用户。

也就是说,您应该确保在用户离开时监听redis用户的socket.on('disconnect')quit()。你也许有兴趣知道socket.io有一个redis后端,它利用了redis pub/sub,它也有房间的概念,所以你可以使用它来节省一些麻烦,因为你已经依赖于socket .IO。

编辑:快速检查后,我得到的Redis此错误消息后,991个用户:

Ready check failed: Error: Error: ERR max number of clients reached 

这里是从默认redis.conf

# Set the max number of connected clients at the same time. By default 
# this limit is set to 10000 clients, however if the Redis server is not 
# able ot configure the process file limit to allow for the specified limit 
# the max number of allowed clients is set to the current file limit 
# minus 32 (as Redis reserves a few file descriptors for internal uses). 
# 
# Once the limit is reached Redis will close all the new connections sending 
# an error 'max number of clients reached'. 
# 
# maxclients 10000 

我的系统(Ubuntu的11.11 )带有1024的默认nofile限制,所以我的快速测试应该在992个连接的客户端之后失败,这似乎是正确的(我也有一个发布者的客户端)。我给你的建议是检查你nofile限制(我的系统上它在/etc/security/limits.{conf,d/*}和你的Redis的maxclients设置,然后标杆,标杆,标杆!

+0

感谢详细的解答。我知道​​socket.io有房概念但我并没有意识到它是在幕后使用pub/sub,我会尝试一下,当然,我会开始基准测试,目前我只是想找到一个好的起点。 – 2012-04-13 19:58:29

+0

@AliErsöz:太好了,如果你发现我的答案是令人满意的,请点击左上方的大号勾号,考虑接受答案为正确答案。 – 2012-04-25 16:27:30