Redisauthentication错误与Node.js和socket.io

我可以连接我的节点应用程序到Redis就好了没有密码,但是当我添加一个密码,没有我做的是对的。

这里是我的代码,从一个例子来看:

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

在运行应用程序,我得到这个堆栈跟踪:

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

产生这个的线是最后一个 – 如果我注释掉设置RedisStore的尝试,我不会得到任何错误。

我敢肯定密码是正确的(我可以在redis-cli中validation它,如果我更改密码是错误的,我可以validationauthcallback不会触发)。 如果我删除密码并注释掉两个auth行,这个代码也可以工作。

所有关于博客文章和文档等的工作示例都表明这应该起作用,而我不知道为什么我的不是。 我不知道要看哪个部分。

当我运行上面的代码时,以下是redis-cli监视器的样子:

 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" 

以下是redis-cli显示器显示的内容,如果我closures密码,注释上面的auth行,并成功运行应用程序:

 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" 

成功的(无密码)连接使得5个“info”命令,并且我的不成功(passworded)命令使得2,然后在对“on_info_cmd”方法的调用中死亡。

任何人都可以理解这一点? 谢谢你提供的所有帮助。

我通过将Redis模块本身作为选项传递给RedisStore构造函数来解决此问题。

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

这对于客户端对象通过instanceof RedisClienttesting的instanceof RedisClient是必要的,不需要重新初始化就没有密码。 显然,当RedisStore重新需要redis模块时,使用createClient方法创build的redis客户端是一些新类的成员。

我通过查看socket.io的问题#808上的一个相关问题来解决这个问题 。

尝试调用redisClient.auth(password, function (err) { if (err) throw err; }); 只有一次,redis存储每个调用的auth信息,调用它两次可能会抛出一个错误。