使用 node_redis 构建一个简单的Redis Pubish订阅(聊天)示例:https://github.com/nelsonic/hapi-socketio-redis-chat-example( with Hapi.js and Socket.io )
我们在项目中创建了一个节点模块 redis_connection.js (参见:http://git.io/vqaos)来实例化Redis连接,因为我们不希望重复多次连接(到RedisCloud)的代码:
var redis = require('redis');
var url = require('url');
var redisURL = url.parse(process.env.REDISCLOUD_URL);
var redisClient = redis.createClient(redisURL.port, redisURL.hostname,
{no_ready_check: true});
redisClient.auth(redisURL.auth.split(":")[1]);
module.exports = redisClient;
然后我们使用这样:
var redisClient = require('./redis_connection.js');
// Confirm we are able to connect to RedisCloud:
redisClient.set('redis', 'working', redisClient.print);
redisClient.get('redis', function (err, reply) {
console.log('RedisCLOUD is ' +reply.toString());
});
这适用于Redis的正常GET / SET操作, 但是当我们尝试实例化Redis的多个连接时(例如:一个发布,另一个订阅,第三个只读GET / SET键/值)我们得到一个错误:
我们看到以下错误:
Error: Connection in subscriber mode, only subscriber commands may be used
我们做错了什么?
我们发现此问题时的完整代码:http://git.io/vqa6y
我们尝试来挖掘现有的SO Q / A,例如:
但未找到完全符合我们情况的解决方案......
(任何建议/帮助非常感谢!)
答案 0 :(得分:3)
未经测试,但评论时间过长。
尝试定义另一个redis连接模块,一个用于常规用法,另一个用于pubsub订阅用途。
为您的项目添加redis_pubsub_connection.js
:
var redis = require('redis');
var url = require('url');
var redisURL = url.parse(process.env.REDISCLOUD_URL);
var redisPubSubClient = redis.createClient(redisURL.port, redisURL.hostname,
{no_ready_check: true});
redisPubSubClient.auth(redisURL.auth.split(":")[1]);
module.exports = redisPubSubClient;
将您的publish.js
require语句更改为:
var redis = require('./redis_pubsub_connection'); // RedisCloud
答案 1 :(得分:2)
为了在我们的项目中保持可重用,我们编写了一个( mini )node.js模块来初始化Redis连接:https://github.com/dwyl/redis-connection < / p>
代码简单且经过测试,如果需要,可以处理 身份验证 。
(不要在此复制粘贴模块以避免重复)
见:https://github.com/dwyl/redis-connection/blob/master/index.js
用法:
npm install redis-connection --save
var redisClient = require('redis-connection')();
redisClient.set('hello', 'world');
redisClient.get('hello', function (err, reply) {
console.log('hello', reply.toString()); // hello world
});
var redisClient = require('redis-connection')(); // Publisher
var redisSub = require('redis-connection')('subscriber');
redisSub.subscribe("chat:messages:latest", "chat:people:new");
有关工作示例,请参阅:https://github.com/dwyl/hapi-socketio-redis-chat-example
优点是我们可以在同一个项目中的多个文件中重复使用相同的redisClient
而无需创建新连接(单个或pub / sub连接被缓存并重新使用)
信用:我们从几个地方借鉴了想法,所以已经投了所有答案。但最终我们编写了一个略有不同的解决方案,因此我们与NPM / GitHub上的所有人分享了它。再次感谢大家!
答案 2 :(得分:1)
问题是您的redis客户端创建代码正在被需要缓存,因此您可以反复使用相同的连接。您可以返回一个函数:
,而不是在redis_connection模块中返回连接module.exports = function(){
var redis = require('redis');
var url = require('url'); var redisURL = url.parse(process.env.REDISCLOUD_URL);
var redisClient = redis.createClient(redisURL.port, redisURL.hostname, {no_ready_check: true});
redisClient.auth(redisURL.auth.split(":")
return redisClient;
}
然后这样称呼它:
var redisClient = require('./redis_connection.js')();
答案 3 :(得分:1)
如果您想提供常规连接和子连接,并且您希望确保在整个应用程序中只有一个连接,那么您可以使用包含单例概念的两个解决方案的组合,如下所示:
var subConnection, con;
var createConnection = module.exports.createConnection = function(){
var redis = require('redis');
var url = require('url'); var redisURL = url.parse(process.env.REDISCLOUD_URL);
var redisClient = redis.createClient(redisURL.port, redisURL.hostname, {no_ready_check: true});
redisClient.auth(redisURL.auth.split(":")
return redisClient;
}
module.exports.getSubConnection = function(){
if (!subConnection)
subConnection = createConnection();
return subConnection
}
module.exports.getConnection = function(){
if (!con)
con = createConnection();
return con
}
}
对其他两种连接类型重复,并将其称为
var con = require('./redis_connection.js').getConnection();