Node.js和socket.io的Redis auth错误

时间:2012-11-18 08:29:58

标签: node.js redis socket.io

我可以将我的Node应用程序连接到Redis,没有密码,但是当我添加密码时,我所做的一切都是正确的。

这是我现在的代码,直接来自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 }));

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

/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中验证它,如果我将密码更改为错误,我可以验证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监视器显示的内容,如果我关闭密码,注释掉上面的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”方法时死亡。

有人能理解这个吗?感谢您提供任何帮助。

2 个答案:

答案 0 :(得分:9)

我通过将redis模块本身作为RedisStore构造函数的选项传递来解决这个问题。

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

这对于客户端对象传递instanceof RedisClient测试是必要的,并且在没有密码的情况下不会重新初始化。显然,当RedisStore重新需要redis模块时,使用createClient方法创建的redis客户端是某些新类的成员或其他东西。

我通过查看某人在socket.io的issue #808上遇到的相关问题来解决这个问题。

答案 1 :(得分:1)

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