diff --git a/loader.js b/loader.js index 9150c868c8..007292bb7c 100644 --- a/loader.js +++ b/loader.js @@ -36,10 +36,6 @@ Loader.init = function (callback) { }; } - if (nconf.get('singleHostCluster')) { - require('socket.io-adapter-cluster/master')(); - } - process.on('SIGHUP', Loader.restart); process.on('SIGUSR2', Loader.reload); process.on('SIGTERM', Loader.stop); @@ -97,6 +93,13 @@ Loader.addWorkerEvents = function (worker) { w.send(message); }); break; + case 'socket.io': + workers.forEach(function (w) { + if (w !== worker) { + w.send(message); + } + }); + break; } } }); diff --git a/src/socket.io/index.js b/src/socket.io/index.js index bf7d7cdd7d..964ebf728c 100644 --- a/src/socket.io/index.js +++ b/src/socket.io/index.js @@ -28,7 +28,9 @@ Sockets.init = function (server) { }); if (nconf.get('singleHostCluster')) { - io.adapter(require('socket.io-adapter-cluster')()); + io.adapter(require('socket.io-adapter-cluster')({ + client: require('./single-host-cluster'), + })); } else if (nconf.get('redis')) { io.adapter(require('../database/redis').socketAdapter()); } else { diff --git a/src/socket.io/single-host-cluster.js b/src/socket.io/single-host-cluster.js new file mode 100644 index 0000000000..c7ca938766 --- /dev/null +++ b/src/socket.io/single-host-cluster.js @@ -0,0 +1,54 @@ +'use strict'; + +var Client = { + sendMessage: function (channel, message) { + process.send({ + action: 'socket.io', + channel: channel, + message: message, + }); + }, + trigger: function (channel, message) { + Client.message.concat(Client.pmessage).forEach(function (callback) { + setImmediate(function () { + callback.call(Client, channel, message); + }); + }); + }, + publish: function (channel, message) { + Client.sendMessage(channel, message); + }, + // we don't actually care about which channels we're subscribed to + subscribe: function () {}, + psubscribe: function () {}, + unsubscribe: function () {}, + unpsubscribe: function () {}, + message: [], + pmessage: [], + on: function (event, callback) { + if (event !== 'message' && event !== 'pmessage') { + return; + } + Client[event].push(callback); + }, + off: function (event, callback) { + if (event !== 'message' && event !== 'pmessage') { + return; + } + if (callback) { + Client[event] = Client[event].filter(function (c) { + return c !== callback; + }); + } else { + Client[event] = []; + } + }, +}; + +process.on('message', function (message) { + if (message && typeof message === 'object' && message.action === 'socket.io') { + Client.trigger(message.channel, message.message); + } +}); + +module.exports = Client;