Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Problem in connection to RedisStorage #808

Closed
zion03 opened this Issue · 19 comments

7 participants

@zion03

I try to make RedisStorage instead of MemoryStorage.
Writen following code:

   var pub = redis.createClient();  
   var sub = redis.createClient();
   var store = redis.createClient();
   pub.auth("pass");
   sub.auth("pass");
   store.auth("pass");

    io.configure( function(){
io.enable('browser client minification');  // send minified client
io.enable('browser client etag');          // apply etag caching logic based on version number
    io.enable('browser client gzip');          // gzip the file
io.set('log level', 1);                    // reduce logging
io.set('transports', [                     // enable all transports (optional if you want flashsocket)
    'websocket'
  , 'flashsocket'
  , 'htmlfile'
  , 'xhr-polling'
  , 'jsonp-polling'
]);
var RedisStore = require('socket.io/lib/stores/redis');
io.set('store', new RedisStore({redisPub:pub, redisSub:sub, redisClient:store}));
    });

And get following error:

      Error: Uncaught, unspecified 'error' event.
     at RedisClient.emit (events.js:50:15)
     at Command.callback (/home/qwe/chat/io2/node_modules/socket.io/node_modules/redis/index.js:232:29)
     at RedisClient.return_error (/home/qwe/chat/io2/node_modules/socket.io/node_modules/redis/index.js:382:25)
     at RedisReplyParser.<anonymous> (/home/qwe/chat/io2/node_modules/socket.io/node_modules/redis/index.js:78:14)
     at RedisReplyParser.emit (events.js:67:17)
     at RedisReplyParser.send_error (    /home/qwe/chat/io2/node_modules/socket.io/node_modules/redis/lib/parser/javascript.js:265:14)
     at RedisReplyParser.execute (/home/qwe/chat/io2/node_modules/socket.io/node_modules/redis/lib/parser/javascript.js:124:22)
     at RedisClient.on_data (/home/qwe/chat/io2/node_modules/socket.io/node_modules/redis/index.js:358:27)
     at Socket.<anonymous> (/home/qwe/chat/io2/node_modules/socket.io/node_modules/redis/index.js:93:14)
     at Socket.emit (events.js:67:17)

Passwords to the Redis exactly right

@3rd-Eden
@zion03

Added events listeners:

pub.auth("pass");
pub.on("error", function (err) {
console.log("Error " + err);
});
sub.auth("pass");
sub.on("error", function (err) {
console.log("Error " + err);
});
store.auth("pass");
store.on("error", function (err) {
console.log("Error " + err);
 });

But the problem remains. Problem in this line io.set('store', new RedisStore({redisPub:pub, redisSub:sub, redisClient:store})); Without this line all working.

@zion03

Perhaps exists some conflicts in the software.
I use:

  • node 0.6.10;
  • node_redis 0.7.1;
  • socket.io 0.8.7;
  • redis 2.4.8. Will Be happy any ideas.
@dshaw

Try defining your error handler before auth. When does the error occur, during execution or at initialization?

@corpulent

Try to require redis like this
redis = require('socket.io/node_modules/redis')

@sandeepeecs

me to facing the same issue ? any fix or workaround of this ?

@dshaw

@sandeepeecs node -v ? Post a gist and I'll have a look.

@sandeepeecs

this is the error log

node.js:134
throw e; // process.nextTick error, or 'error' event on first tick
^
Error: Uncaught, unspecified 'error' event.
at RedisClient.emit (events.js:47:15)
at Command.callback (/var/vcap/data/dea/apps/hackfestchat-0-b615adbc35e98b62092eb7b548881109/app/node_modules/socket.io/node_modules/redis/index.js:232:15)
at RedisClient.return_error (/var/vcap/data/dea/apps/hackfestchat-0-b615adbc35e98b62092eb7b548881109/app/node_modules/socket.io/node_modules/redis/index.js:383:25)
at RedisReplyParser. (/var/vcap/data/dea/apps/hackfestchat-0-b615adbc35e98b62092eb7b548881109/app/node_modules/socket.io/node_modules/redis/index.js:78:14)
at RedisReplyParser.emit (events.js:64:17)
at RedisReplyParser.send_error (/var/vcap/data/dea/apps/hackfestchat-0-b615adbc35e98b62092eb7b548881109/app/node_modules/socket.io/node_modules/redis/lib/parser/javascript.js:265:14)
at RedisReplyParser.execute (/var/vcap/data/dea/apps/hackfestchat-0-b615adbc35e98b62092eb7b548881109/app/node_modules/socket.io/node_modules/redis/lib/parser/javascript.js:124:22)
at RedisClient.on_data (/var/vcap/data/dea/apps/hackfestchat-0-b615adbc35e98b62092eb7b548881109/app/node_modules/socket.io/node_modules/redis/index.js:359:27)
at Socket. (/var/vcap/data/dea/apps/hackfestchat-0-b615adbc35e98b62092eb7b548881109/app/node_modules/socket.io/node_modules/redis/index.js:93:14)
at Socket.emit (events.js:64:17)

and i am trying to install https://github.com/gravityonmars/Balloons.IO on cloudfoundry.

@dshaw

Do you have an instance of Redis running on localhost?

https://github.com/gravityonmars/Balloons.IO/blob/master/balloons.js#L145 assumes you have Redis running on localhost.

@justoneplanet

In my case,
the file (node_modules/socket.io/lib/stores/redis.js) had some problems.
opts.redisPub is not instance of redis.RedisClient at following lines.

 63   var redis = opts.redis || require('redis')
 64     , RedisClient = redis.RedisClient;
 65 
 66   // initialize a pubsub client and a regular client
 67   //if (opts.redisPub instanceof RedisClient) {
 68     this.pub = opts.redisPub;
 69   //} else {
 70   //  opts.redisPub || (opts.redisPub = {});
 71   //  this.pub = redis.createClient(opts.redisPub.port, opts.redisPub.host, opts.redisPub);
 72   //}
 73   //if (opts.redisSub instanceof RedisClient) {
 74     this.sub = opts.redisSub;
 75   //} else {
 76   //  opts.redisSub || (opts.redisSub = {});
 77   //  this.sub = redis.createClient(opts.redisSub.port, opts.redisSub.host, opts.redisSub);
 78   //}
 79   //if (opts.redisClient instanceof RedisClient) {
 80     this.cmd = opts.redisClient;
 81   //} else {
 82   //  opts.redisClient || (opts.redisClient = {});
 83   //  this.cmd = redis.createClient(opts.redisClient.port, opts.redisClient.host, opts.redisClient);
 84   //}

In app.js, redisPub is instance of redis.RedisClient.
In the above js, redisPub is not instance of redis.RedisClient.
That is why stores/redis.js re-create a redis client not having "auth", "error" and display error messages like you.

I don't know why redisPub is not instance of redis.RedisClient in the above js though redisPub is instance of redis.RedisClient in app.js.

@dshaw

Post a gist. Without seeing how your inputs, it's impossible to tell.

Pass in fully configured instances of node_redis RedisClient with auth, db, error and all the production configurations you need. Pub and Sub must be distinct instances becuase the SUBSCRIBE command puts the redis client into a special mode.

@justoneplanet

In my app.js,
I' m using the following code

var io = socketio.listen(app);
io.configure(function(){
  var redisPub    = redis.createClient(conf['redis']['port'], conf['redis']['host']);
  var redisSub    = redis.createClient(conf['redis']['port'], conf['redis']['host']);
  var redisClient = redis.createClient(conf['redis']['port'], conf['redis']['host']);
  redisPub.on('error', function(err){console.error(err)});
  redisSub.on('error', function(err){console.error(err)});
  redisClient.on('error', function(err){console.error(err)});
  redisPub.auth(conf['redis']['password']);
  redisSub.auth(conf['redis']['password']);
  redisClient.auth(conf['redis']['password']);
  io.set('store', new SocketRedisStore({
    "redisPub"    : redisPub,
    "redisSub"    : redisSub,
    "redisClient" : redisClient
  }));

In the file (node_modules/socket.io/lib/stores/redis.js),
I think you believe that
"opts.redisPub instanceof RedisClient" is "true".

In my case,
"opts.redisPub instanceof RedisClient" is "false"
I don't know why.

Because it is false, createClient reruns without error and auth.

@dshaw

And you tested both redisSub and redisClient return true for instanceof RedisClient?

Which node_redis is this?

What's your npm ls?

@justoneplanet

And you tested both redisSub and redisClient return true for instanceof RedisClient?

Yes.
To be exact, I tested by the following code

var io = socketio.listen(app);
io.configure(function(){
  var redisPub    = redis.createClient(conf['redis']['port'], conf['redis']['host']);
  var redisSub    = redis.createClient(conf['redis']['port'], conf['redis']['host']);
  var redisClient = redis.createClient(conf['redis']['port'], conf['redis']['host']);
  redisPub.on('error', function(err){console.error(err)});
  redisSub.on('error', function(err){console.error(err)});
  redisClient.on('error', function(err){console.error(err)});
  redisPub.auth(conf['redis']['password']);
  redisSub.auth(conf['redis']['password']);
  redisClient.auth(conf['redis']['password']);
console.log(redisPub instanceof redis.RedisClient);// true
console.log(redisSub instanceof redis.RedisClient);// true
console.log(redisClient instanceof redis.RedisClient);// true
  io.set('store', new SocketRedisStore({
    "redisPub"    : redisPub,
    "redisSub"    : redisSub,
    "redisClient" : redisClient
  }));

What's your npm ls?

├─┬ apn@1.2.3
│ └── q@0.8.6
├─┬ connect@2.3.3 extraneous
│ ├── bytes@0.0.1
│ ├── cookie@0.0.3
│ ├── crc@0.2.0
│ ├── debug@0.7.0
│ ├── formidable@1.0.11
│ ├── fresh@0.0.1
│ ├── mime@1.2.4
│ ├── qs@0.4.2
│ └── range-parser@0.0.1
├── debug@0.7.0
├── ejs@0.7.1
├─┬ express@2.5.8
│ ├─┬ connect@1.8.7
│ │ └── formidable@1.0.9
│ ├── mime@1.2.4
│ ├── mkdirp@0.3.0
│ └── qs@0.4.2
├─┬ jade@0.26.0
│ ├── commander@0.5.2
│ └── mkdirp@0.3.0
├─┬ mysql@2.0.0-alpha2
│ └── require-all@0.0.3
├── node-gcm@0.9.2
├─┬ redis@0.7.2
│ └── hiredis@0.1.14
├─┬ socket.io@0.9.6
│ ├── policyfile@0.0.4
│ ├── redis@0.6.7
│ └─┬ socket.io-client@0.9.6
│   ├─┬ active-x-obfuscator@0.0.1
│   │ └── zeparser@0.0.5
│   ├── uglify-js@1.2.5
│   ├─┬ ws@0.4.15
│   │ ├── commander@0.5.2
│   │ └── options@0.0.3
│   └── xmlhttprequest@1.2.2
└─┬ twitter@0.1.18
  ├── cookies@0.3.0
  ├── keygrip@0.2.0
  └── oauth@0.9.7

..under examination...

@dshaw

Try passing in your redis in with your options:

io.set('store', new SocketRedisStore({
    "redis"    : redis,    
    "redisPub"    : redisPub,
    "redisSub"    : redisSub,
    "redisClient" : redisClient
  }));

Even better, update your socket.io. You should be > 0.9.6 for RedisStore. Current is v0.9.10.

@justoneplanet

Great!

Your code solves the problem, using v0.9.6.

After I upgraded socket.io to v0.9.10, I have got another error like following...

http.js:644
    throw new Error('Can\'t set headers after they are sent.');
          ^
Error: Can't set headers after they are sent.
    at ServerResponse.OutgoingMessage.setHeader (http.js:644:11)
    at ServerResponse.res.setHeader (node_modules/express/node_modules/connect/lib/patch.js:62:20)
    at next (node_modules/express/node_modules/connect/lib/http.js:171:13)
    at exports.send (node_modules/express/node_modules/connect/lib/middleware/static.js:150:11)
    at Object.oncomplete (fs.js:308:15)
    at process.startup.processMakeCallback.process._makeCallback (node.js:248:20)
@dshaw

@justoneplanet Glad to hear that. Sounds like you might need to upgrade Express / Connect. Either way, it's very much out of RedisStore, so you should probably debug that off this thread. :shipit:

@konklone

I just got bit with this issue, in the most current version (0.9.11), although at first it looked different. I also solved it by passing in my copy of the redis module as the redis option in the call to the RedisStore constructor.

My call to set the RedisStore was generating an unauthorized error, even though I was passing in authorized clients. It turned out that the instanceof checks were failing, because (I think) the class of redis.RedisClient that my clients were created as was different than the class of redis.RedisClient that RedisStore was checking against -- because it had re-imported the redis module. I guess that makes sense, since JavaScript is prototype based and not class based...? Maybe?

Either way: I just updated the wiki's configuring page to add an example of using RedisStore with authorization. I think this ticket's root cause has been discovered and addressed, and can be closed.

This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.