2012-04-13 7 views
14

Ich bin neu in Redis Pub/Sub. Ich habe eine Chat-Funktion im System, die wie IM ist. Also würde ich gerne redis pub/sub benutzen. Wie ich die Proben untersucht habe, sind die meisten von ihnen basierend auf einem Chat-Room entworfen. In meinem System werde ich mehrere Chat-Räume zwischen Benutzern haben wie;Wie Redis Pub/Sub für ein Instant Messaging-System zu entwerfen?

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

Also, die Zeilen oben sind die Zimmer. Und ich habe den Server mit node.js wie unten implementiert;

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)) 
     }); 
    }); 
}); 

Wie Sie sehen können, erstelle ich einen neuen Redis-Abonnenten für jede Verbindung. In anderen Chat-Room-Beispielen wird der Redis Subscriber-Client global erstellt. Und es gibt immer nur drei Verbindungen, und das löst ihr Problem, denn wenn ein Herausgeber eine Nachricht veröffentlicht, sollten alle verbundenen Clients sie bekommen. Aber ich habe hier eine Einschränkung. Ich möchte eine Chat-Sitzung zwischen zwei Benutzern öffnen und nur diese Benutzer sollten die Abonnenten sein. Der obige Code funktioniert wie ich möchte, aber ich weiß nicht, ob es für redis in Ordnung ist, einen neuen Abonnenten-Client für jede Verbindung zu erstellen.

Es wäre schön, Ihre Vorschläge zu hören. Danke im Voraus.

Antwort

20

Wie immer müssen Sie solche Dinge für Ihren eigenen Anwendungsfall vergleichen - es ist nicht möglich, allgemeine Hinweise zu geben. Möglicherweise müssen Sie die maximale Anzahl der geöffneten Dateien auf Ihrem System entweder systemweit oder für den Redis-Benutzer erhöhen. Dies gilt natürlich auch für den Benutzer, der Ihren Webserver betreibt.

Das heißt, Sie sollten sicherstellen, für socket.on('disconnect') und quit() den Redis-Abonnenten zu hören, wenn ein Benutzer verlässt. Sie könnten auch interessiert sein zu wissen, dass socket.io ein Redis-Backend hat, welches redis pub/sub nutzt, und es hat auch das Konzept von rooms, so dass Sie sich damit ein paar Probleme ersparen können, da Sie bereits vom Socket abhängig sind .io.

Edit: Nach einer kurzen Überprüfung, erhalte ich diese Fehlermeldung von Redis nach 991 Abonnenten:

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

Hier ist von dem Standard 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 

Mein System (Ubuntu 11.11) kommt mit einem Standard nofile Limit von 1024, so dass mein schneller Test nach 992 verbundenen Clients fehlschlagen sollte, was ungefähr aus dem Test scheint (ich habe auch einen Client für den Herausgeber). Mein Vorschlag an Sie ist Ihre nofile Grenze (auf meinem System zu inspizieren es in /etc/security/limits.{conf,d/*} und Ihre redis maxclients Einstellung, und dann Benchmark Benchmark Benchmark!

+0

Dank für die ausführliche Antwort. Ich wusste, dass socket.io hat das Raumkonzept Aber ich wusste nicht, dass es Pub/Sub hinter den Kulissen benutzt, ich werde es versuchen und ich werde die Benchmark Tests starten, momentan versuche ich nur einen guten Startpunkt zu finden Vorschläge –

+0

@ AliErsöz: Großartig.Wenn Sie herausfinden, meine Antwort war zufriedenstellend, bitte betrachten Sie es als die richtige Antwort akzeptieren, indem Sie auf das große Häkchen oben links klicken. –