Error de autenticación Redis con Node.js y socket.io

Puedo conectar mi aplicación Node a Redis sin ninguna contraseña, pero cuando agrego una contraseña, nada de lo que hago es correcto.

Aquí está mi código ahora mismo, tomado de un ejemplo :

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

Al ejecutar la aplicación, obtengo este seguimiento de stack:

 /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. (/home/eric/christmas/sockets/node_modules/socket.io/node_modules/redis/index.js:79:14) at Socket.EventEmitter.emit (events.js:93:17) 

La línea que genera esto es la última: si comento el bash de configurar RedisStore, no obtengo ningún error.

Estoy seguro de que la contraseña es correcta (puedo verificarla en redis-cli, y si la cambio es incorrecta, puedo verificar que las devoluciones de llamada de autenticación no se activen). Este código también funciona si elimino la contraseña y comento las dos líneas de autenticación.

Todos los ejemplos de trabajo en publicaciones y documentos de blogs y similares muestran que esto debería funcionar, y no sé por qué el mío no lo es. No sé qué parte de la stack mirar.

Aquí es cómo se ve el monitor redis-cli cuando ejecuto el código anterior:

 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" 

Y esto es lo que muestra el monitor redis-cli si desactivo la contraseña, comento las líneas de autenticación anteriores y ejecuto la aplicación con éxito:

 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" 

La conexión exitosa (sin contraseña) realiza 5 comandos “info”, y mi comando no exitoso (con contraseña) crea 2, y luego muere en una llamada a un método “on_info_cmd”.

¿Alguien puede dar sentido a esto? Gracias por cualquier ayuda que usted puede dar.

Resolví esto pasando el módulo redis en sí mismo como una opción al constructor RedisStore.

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

Esto fue necesario para que los objetos del cliente pasen la instanceof RedisClient prueba instanceof RedisClient y no se puedan reiniciar sin una contraseña. Aparentemente, cuando RedisStore requiere el módulo redis, los clientes redis creados con el método createClient son miembros de alguna clase nueva o algo así.

Descubrí esto mirando un problema relacionado que alguien tenía en el número 808 de socket.io.

Intente llamar a redisClient.auth(password, function (err) { if (err) throw err; }); solo una vez, redis almacena la información de autenticación para cada llamada, llamándola dos veces puede generar un error.