I can connect my Node app to Redis just fine without a password, but when I add a password, nothing I do is right.
Here's my code right now, taken right from an example:
var redis = require('redis')
, sio = require('socket.io')
, RedisStore = sio.RedisStore
, io = sio.listen();
var port = 6379
, hostname = 'localhost'
, password = 'password';
var redisClient = redis.createClient(port, hostname);
redisClient.auth(password, function (err) { if (err) throw err; });
var redisSubscriber = redis.createClient(port, hostname);
redisSubscriber.auth(password, function (err) { if (err) throw err; });
io.set('store', new RedisStore({ redisPub: redisClient, redisSub: redisSubscriber, redisClient: redisClient }));
On running the app, I get this stack trace:
/home/eric/christmas/sockets/node_modules/socket.io/node_modules/redis/index.js:506
throw callback_err;
^
Error: Ready check failed: ERR operation not permitted
at RedisClient.on_info_cmd (/home/eric/christmas/sockets/node_modules/socket.io/node_modules/redis/index.js:319:35)
at Command.RedisClient.ready_check.send_anyway [as callback] (/home/eric/christmas/sockets/node_modules/socket.io/node_modules/redis/index.js:367:14)
at RedisClient.return_error (/home/eric/christmas/sockets/node_modules/socket.io/node_modules/redis/index.js:502:25)
at RedisReplyParser.RedisClient.init_parser (/home/eric/christmas/sockets/node_modules/socket.io/node_modules/redis/index.js:262:14)
at RedisReplyParser.EventEmitter.emit (events.js:93:17)
at RedisReplyParser.send_error (/home/eric/christmas/sockets/node_modules/socket.io/node_modules/redis/lib/parser/javascript.js:266:14)
at RedisReplyParser.execute (/home/eric/christmas/sockets/node_modules/socket.io/node_modules/redis/lib/parser/javascript.js:125:22)
at RedisClient.on_data (/home/eric/christmas/sockets/node_modules/socket.io/node_modules/redis/index.js:478:27)
at Socket.<anonymous> (/home/eric/christmas/sockets/node_modules/socket.io/node_modules/redis/index.js:79:14)
at Socket.EventEmitter.emit (events.js:93:17)
The line generating this is the final one - if I comment out the attempt to set the RedisStore, I do not get any errors.
I'm sure the password is right (I can verify it in redis-cli, and if I change the password to be wrong I can verify that the auth callbacks don't fire). This code also works if I remove the password and comment out the two auth lines.
All of the working examples on blog posts and docs and the like show that this should work, and I don't know why mine isn't. I don't know which part of the stack to look at.
Here's what the redis-cli monitor looks like when I run the code above:
1353227107.912512 [0 127.0.0.1:56759] "auth" "password"
1353227107.912719 [0 127.0.0.1:56758] "auth" "password"
1353227107.913470 [0 127.0.0.1:56759] "info"
1353227107.913639 [0 127.0.0.1:56758] "info"
And here's what redis-cli monitor shows if I turn off the password, comment out the auth lines above, and successfully run the app:
1353227252.401667 [0 127.0.0.1:56771] "info"
1353227252.402020 [0 127.0.0.1:56770] "info"
1353227252.402131 [0 127.0.0.1:56769] "info"
1353227252.402423 [0 127.0.0.1:56768] "info"
1353227252.402611 [0 127.0.0.1:56767] "info"
1353227252.406254 [0 127.0.0.1:56770] "subscribe" "handshake"
1353227252.406287 [0 127.0.0.1:56770] "subscribe" "connect"
1353227252.406314 [0 127.0.0.1:56770] "subscribe" "open"
1353227252.406321 [0 127.0.0.1:56770] "subscribe" "join"
1353227252.406326 [0 127.0.0.1:56770] "subscribe" "leave"
1353227252.406337 [0 127.0.0.1:56770] "subscribe" "close"
1353227252.406354 [0 127.0.0.1:56770] "subscribe" "dispatch"
1353227252.406372 [0 127.0.0.1:56770] "subscribe" "disconnect"
The successful (passwordless) connection makes 5 "info" commands, and my unsuccessful (passworded) command makes 2 - and then dies on a call to an "on_info_cmd" method.
Can anyone make sense of this? Thanks for any help you can give.
In order to use Redis with Node.js, you need to install a Node.js Redis client. The following sections demonstrate the use of ioredis, a community-recommended Redis client for Node.js with build-in support for promises. Another community-recommended client for Node.js developers is node_redis.
The following sections demonstrate the use of ioredis, a community-recommended Redis client for Node.js with build-in support for promises. Another community-recommended client for Node.js developers is node_redis. Additional Node.js clients for Redis can be found under the Node.js section of the Redis Clients page.
We will use the socket.io-redis adapter provided by Socket.IO. This Redis server is used for its pub/sub functionality to coordinate events across multiple Socket.IO instances such as new sockets joining, exchanging messages, or disconnects.
Socket.IO. A JavaScript library for real-time web applications that enables real-time, bi-directional communication between web clients and servers. Socket.IO has two components: a client-side library that runs in the browser, and a server-side library for Node.js. Both components have nearly identical APIs.
I solved this by passing the redis module itself as an option to the RedisStore constructor.
io.set('store', new RedisStore({redis: redis, redisPub: redisClient, redisSub: redisSubscriber, redisClient: redisClient }));
This was necessary for the client objects to pass the instanceof RedisClient
test and not be re-initialized without a password. Apparently, when RedisStore
re-requires the redis module, redis clients created with the createClient
method are members of some new class or something.
I figured this out by looking at a related issue someone was having on socket.io's issue #808.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With