UNPKG

activestack-gateway

Version:
126 lines (98 loc) 2.58 kB
/** * Module dependencies. */ var uid2 = require('uid2'); var redis = require('redis').createClient; var msgpack = require('msgpack-js'); var Adapter = require('socket.io-adapter'); var Emitter = require('events').EventEmitter; var debug = require('debug')('socket.io-redis'); /** * Module exports. */ module.exports = adapter; /** * Returns a redis Adapter class. * * @param {String} optional, redis uri * @return {RedisAdapter} adapter * @api public */ function adapter(uri, opts){ opts = opts || {}; // handle options only if ('object' == typeof uri) { opts = uri; uri = null; } // handle uri string if (uri) { uri = uri.split(':'); opts.host = uri[0]; opts.port = uri[1]; } // opts var socket = opts.socket; var host = opts.host || '127.0.0.1'; var port = Number(opts.port || 6379); var pub = opts.pubClient; var sub = opts.subClient; var prefix = opts.key || 'socket.io'; // init clients if needed if (!pub) pub = socket ? redis(socket) : redis(port, host); if (!sub) sub = socket ? redis(socket, { detect_buffers: true }) : redis(port, host, {detect_buffers: true}); // this server's key var uid = uid2(6); var key = prefix + '#' + uid; /** * Adapter constructor. * * @param {String} namespace name * @api public */ function Redis(nsp){ Adapter.call(this, nsp); var self = this; sub.psubscribe(prefix + '#*', function(err){ if (err) self.emit('error', err); }); sub.on('pmessage', this.onmessage.bind(this)); } /** * Inherits from `Adapter`. */ Redis.prototype.__proto__ = Adapter.prototype; /** * Called with a subscription message * * @api private */ Redis.prototype.onmessage = function(pattern, channel, msg){ var pieces = channel.split('#'); if (uid == pieces.pop()) return debug('ignore same uid'); var args = msgpack.decode(msg); if (args[0] && args[0].nsp === undefined) { args[0].nsp = '/'; } if (!args[0] || args[0].nsp != this.nsp.name) { return debug('ignore different namespace'); } args.push(true); this.broadcast.apply(this, args); }; /** * Broadcasts a packet. * * @param {Object} packet to emit * @param {Object} options * @param {Boolean} whether the packet came from another node * @api public */ Redis.prototype.broadcast = function(packet, opts, remote){ Adapter.prototype.broadcast.call(this, packet, opts); if (!remote) pub.publish(key, msgpack.encode([packet, opts])); }; return Redis; }