How to reuse redis connection in socket.io?


Question

Here is my code using socket.io as WebSocket and backend with 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();
    });
});

Every new io request will create new redis connection. If someone open browser with 100 tabs then the redis client will open 100 connections. It doesn't look nice.

Is it possible to reuse redis connection if the cookies are same? So if someone open many browser tabs also treat as open 1 connection.

1
40
4/21/2011 9:22:10 AM

Accepted Answer

Actually you are only creating a new redis client for every connection if you are instantiating the client on the "connection" event. What I prefer to do when creating a chat system is to create three redis clients. One for publishing, subscribing, and one for storing values into redis.

for example:

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

})
60
4/21/2011 8:49:58 PM

Redis is optimized for a high level of concurrent connections. There is also discussion about multiple database connections and connection pool implementation in node_redis module.

Is it possible to reuse redis connection if the cookies are same? So if someone open many browser tabs also treat as open 1 connection.

You can use for example HTML5 storage on the client side to keep actively connected only one tab and others will handle communication/messages through storage events. It's related to this question.


Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon