40 votes

Comment réutiliser le redis connexion de socket.io?

Voici mon code à l'aide de socket.io comme WebSocket et backend avec pub/sub redis.

var io = io.listen(server),
    buffer = [];

var redis = require("redis");

var subscribe = redis.createClient();  **<--- open new connection overhead**

io.on('connection', function(client) {

    console.log(client.request.headers.cookie);

    subscribe.get("..", function (err, replies) {

    });

    subscribe.on("message",function(channel,message) {

        var msg = { message: [client.sessionId, message] };
        buffer.push(msg);
        if (buffer.length > 15) buffer.shift();
        client.send(msg);
    });

    client.on('message', function(message){
    });

    client.on('disconnect', function(){
        subscribe.quit();
    });
});

Chaque nouvelle demande d'e / s permettra de créer de nouveaux redis connexion. Si quelqu'un navigateur ouvert avec 100 onglets puis le redis client sera ouvert 100 connexions. Il n'a pas l'air gentil.

Est-il possible de réutiliser redis connexion si les cookies sont de même? Donc, si quelqu'un ouvrir plusieurs onglets du navigateur de considérer également comme ouvrir 1 connexion.

60voto

sintaxi Points 795

En fait, vous ne sont la création d'une nouvelle redis client pour chaque connexion si vous êtes l'instanciation du client sur le "connexion" de l'événement. Ce que je préfère le faire lors de la création d'un système de chat est de créer trois redis clients. L'un pour la publication, de l'abonnement, et une pour stocker les valeurs dans le redis.

par exemple:

var socketio = require("socket.io")
var redis = require("redis")

// redis clients
var store = redis.createClient()
var pub = redis.createClient()
var sub = redis.createClient()

// ... application paths go here

var socket = socketio.listen(app)

sub.subscribe("chat")

socket.on("connection", function(client){
  client.send("welcome!")

  client.on("message", function(text){
    store.incr("messageNextId", function(e, id){
      store.hmset("messages:" + id, { uid: client.sessionId, text: text }, function(e, r){
        pub.publish("chat", "messages:" + id)
      })
    })
  })

  client.on("disconnect", function(){
    client.broadcast(client.sessionId + " disconnected")
  })

  sub.on("message", function(pattern, key){
    store.hgetall(key, function(e, obj){
      client.send(obj.uid + ": " + obj.text)
    })
  })

})

2voto

yojimbo87 Points 27744

Redis est optimisé pour un niveau élevé de connexions simultanées. Il y a aussi une discussion sur les multiples connexions de base de données et le pool de connexion de la mise en œuvre dans node_redis module.

Est-il possible de réutiliser redis connexion si les cookies sont de même? Donc si quelqu'un ouvrir plusieurs onglets du navigateur aussi traiter comme ouvrir 1 connexion.

Vous pouvez utiliser, par exemple, HTML5 de stockage sur le côté client pour garder la connexion active un seul onglet et d'autres vont gérer la communication/des messages à travers les événements de stockage. C'est lié à cette question.

1voto

Josh Mc Points 1408

J'ai eu exactement ce problème, avec en plus une exigence que les clients doivent être en mesure de s'abonner à des chaînes privées, et de publier à ces canaux ne doivent pas être envoyés à tous les auditeurs. J'ai essayé de résoudre ce problème en écrivant une miniature plugin. Le plugin:

  • Utilise seulement 2 redis connexions, l'une pour pub, une pour les sous
  • Seulement s'abonne à "message" une fois de total (et non une fois tous les redis connexion)
  • Permettre aux clients de s'abonner à leurs propres chaînes privées, sans les messages envoyés à tous les autres à l'écoute des clients.

Particulièrement utile si votre prototypage dans un endroit où vous avez une redis limite de connexion (comme redis-to-go). DONC, le lien: http://stackoverflow.com/a/16770510/685404

1voto

nakwa Points 68

Vous devez supprimer l'auditeur lors de la déconnexion du client.

var io = io.listen(server),
    buffer = [];

var redis = require("redis");

var subscribe = redis.createClient();  

io.on('connection', function(client) {

    console.log(client.request.headers.cookie);

    subscribe.get("..", function (err, replies) {

    });

    var redis_handler = function(channel,message) {

        var msg = { message: [client.sessionId, message] };
        buffer.push(msg);
        if (buffer.length > 15) buffer.shift();
        client.send(msg);
    };

    subscribe.on("message", redis_handler);


    client.on('message', function(message){
    });

    client.on('disconnect', function(){
        subscribe.removeListerner('message', redis_handler)
        //subscribe.quit();
    });
});

Voir le Redis, Node.js et Socket.io : inter-serveur d'authentification et node.js la compréhension

0voto

cmcculloh Points 11040

Utilisation de redis comme un magasin est devenu beaucoup plus simple depuis que cette question a été posée/réponse. Il est construit en maintenant.

Notez que si vous utilisez le redis parce que vous êtes en utilisant le nouveau nœud de clustering capacités (en utilisant plusieurs Processeurs), vous devez créer le serveur et raccordez les écouteurs à l'intérieur de chaque cluster fourches (ce n'est jamais vraiment expliqué nulle part dans la documentation ;) ). Le seul bon exemple de code en ligne que j'ai trouvé est écrit en CoffeeScript et je vois beaucoup de gens qui disent ce genre de chose "ne marche pas", et il n'a certainement pas si vous le faites mal. Voici un exemple de "faire droit" (mais il est en CoffeeScript)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X