From f41be4ae8ba109540ff287f8ebf3e0d17c1d922c Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Tue, 23 Sep 2014 17:08:30 -0400 Subject: [PATCH] exposed redis' "connect" method, so socket.io can call it from outside database/redis.js, fixed NodeBB requiring Redis as a socket.io store. It will now go back to using in-memory store per process, if no redis config is found in the NodeBB configuration. re: #2097 --- src/database/redis.js | 49 +++++++++++++++++++++++++----------------- src/socket.io/index.js | 41 +++++++++++++++++++++-------------- 2 files changed, 54 insertions(+), 36 deletions(-) diff --git a/src/database/redis.js b/src/database/redis.js index 0becf2ba9e..09d13d6cf8 100644 --- a/src/database/redis.js +++ b/src/database/redis.js @@ -47,26 +47,7 @@ process.exit(); } - var redis_socket_or_host = nconf.get('redis:host'); - - if (redis_socket_or_host && redis_socket_or_host.indexOf('/')>=0) { - /* If redis.host contains a path name character, use the unix dom sock connection. ie, /tmp/redis.sock */ - redisClient = redis.createClient(nconf.get('redis:host')); - } else { - /* Else, connect over tcp/ip */ - redisClient = redis.createClient(nconf.get('redis:port'), nconf.get('redis:host')); - } - - if (nconf.get('redis:password')) { - redisClient.auth(nconf.get('redis:password')); - } else { - winston.warn('You have no redis password setup!'); - } - - redisClient.on('error', function (err) { - winston.error(err.stack); - process.exit(1); - }); + redisClient = module.connect(); module.client = redisClient; @@ -104,6 +85,34 @@ } }; + module.connect = function() { + var redis_socket_or_host = nconf.get('redis:host'), + cxn; + + if (!redis) redis = require('redis'); + + if (redis_socket_or_host && redis_socket_or_host.indexOf('/') >= 0) { + /* If redis.host contains a path name character, use the unix dom sock connection. ie, /tmp/redis.sock */ + cxn = redis.createClient(nconf.get('redis:host')); + } else { + /* Else, connect over tcp/ip */ + cxn = redis.createClient(nconf.get('redis:port'), nconf.get('redis:host')); + } + + if (nconf.get('redis:password')) { + cxn.auth(nconf.get('redis:password')); + } else { + winston.warn('You have no redis password setup!'); + } + + cxn.on('error', function (err) { + winston.error(err.stack); + process.exit(1); + }); + + return cxn; + }; + module.close = function() { redisClient.quit(); }; diff --git a/src/socket.io/index.js b/src/socket.io/index.js index 6f949177d1..354e72516e 100644 --- a/src/socket.io/index.js +++ b/src/socket.io/index.js @@ -66,23 +66,32 @@ function onUserDisconnect(uid, socketid, socketCount) { } Sockets.init = function(server) { - var RedisStore = require('socket.io/lib/stores/redis'), - redis = require('redis'), - pub = redis.createClient(), - sub = redis.createClient(), - client = redis.createClient(); + // Default socket.io config + var config = { + log: false, + transports: ['websocket', 'xhr-polling', 'jsonp-polling', 'flashsocket'], + 'browser client minification': true, + resource: nconf.get('relative_path') + '/socket.io' + }; - io = socketioWildcard(SocketIO).listen(server, { - log: false, - transports: ['websocket', 'xhr-polling', 'jsonp-polling', 'flashsocket'], - 'browser client minification': true, - resource: nconf.get('relative_path') + '/socket.io', - 'store' : new RedisStore({ - redisPub : pub, - redisSub : sub, - redisClient : client - }), - }); + // If a redis server is configured, use it as a socket.io store, otherwise, fall back to in-memory store + if (nconf.get('redis')) { + var RedisStore = require('socket.io/lib/stores/redis'), + database = require('../database/redis'), + pub = database.connect(), + sub = database.connect(), + client = database.connect(); + + config.store = new RedisStore({ + redisPub : pub, + redisSub : sub, + redisClient : client + }); + } else if (nconf.get('cluster')) { + winston.warn('[socket.io] Clustering detected, you are advised to configure Redis as a websocket store.') + } + + io = socketioWildcard(SocketIO).listen(server, config); Sockets.server = io;