2012-04-13 138 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