You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

144 lines
3.1 KiB

  1. /**
  2. * Module dependencies.
  3. */
  4. var keys = require('object-keys');
  5. var Emitter = require('events').EventEmitter;
  6. var parser = require('socket.io-parser');
  7. /**
  8. * Module exports.
  9. */
  10. module.exports = Adapter;
  11. /**
  12. * Memory adapter constructor.
  13. *
  14. * @param {Namespace} nsp
  15. * @api public
  16. */
  17. function Adapter(nsp){
  18. this.nsp = nsp;
  19. this.rooms = {};
  20. this.sids = {};
  21. this.encoder = new parser.Encoder();
  22. }
  23. /**
  24. * Inherits from `EventEmitter`.
  25. */
  26. Adapter.prototype.__proto__ = Emitter.prototype;
  27. /**
  28. * Adds a socket from a room.
  29. *
  30. * @param {String} socket id
  31. * @param {String} room name
  32. * @param {Function} callback
  33. * @api public
  34. */
  35. Adapter.prototype.add = function(id, room, fn){
  36. this.sids[id] = this.sids[id] || {};
  37. this.sids[id][room] = true;
  38. this.rooms[room] = this.rooms[room] || {};
  39. this.rooms[room][id] = true;
  40. if (fn) process.nextTick(fn.bind(null, null));
  41. };
  42. /**
  43. * Removes a socket from a room.
  44. *
  45. * @param {String} socket id
  46. * @param {String} room name
  47. * @param {Function} callback
  48. * @api public
  49. */
  50. Adapter.prototype.del = function(id, room, fn){
  51. this.sids[id] = this.sids[id] || {};
  52. this.rooms[room] = this.rooms[room] || {};
  53. delete this.sids[id][room];
  54. delete this.rooms[room][id];
  55. if (this.rooms.hasOwnProperty(room) && !keys(this.rooms[room]).length) {
  56. delete this.rooms[room];
  57. }
  58. if (fn) process.nextTick(fn.bind(null, null));
  59. };
  60. /**
  61. * Removes a socket from all rooms it's joined.
  62. *
  63. * @param {String} socket id
  64. * @api public
  65. */
  66. Adapter.prototype.delAll = function(id, fn){
  67. var rooms = this.sids[id];
  68. if (rooms) {
  69. for (var room in rooms) {
  70. if (rooms.hasOwnProperty(room)) {
  71. delete this.rooms[room][id];
  72. }
  73. if (this.rooms.hasOwnProperty(room) && !keys(this.rooms[room]).length) {
  74. delete this.rooms[room];
  75. }
  76. }
  77. }
  78. delete this.sids[id];
  79. };
  80. /**
  81. * Broadcasts a packet.
  82. *
  83. * Options:
  84. * - `flags` {Object} flags for this packet
  85. * - `except` {Array} sids that should be excluded
  86. * - `rooms` {Array} list of rooms to broadcast to
  87. *
  88. * @param {Object} packet object
  89. * @api public
  90. */
  91. Adapter.prototype.broadcast = function(packet, opts){
  92. var rooms = opts.rooms || [];
  93. var except = opts.except || [];
  94. var flags = opts.flags || {};
  95. var ids = {};
  96. var self = this;
  97. var socket;
  98. packet.nsp = this.nsp.name;
  99. this.encoder.encode(packet, function(encodedPackets) {
  100. if (rooms.length) {
  101. for (var i = 0; i < rooms.length; i++) {
  102. var room = self.rooms[rooms[i]];
  103. if (!room) continue;
  104. for (var id in room) {
  105. if (room.hasOwnProperty(id)) {
  106. if (ids[id] || ~except.indexOf(id)) continue;
  107. socket = self.nsp.connected[id];
  108. if (socket) {
  109. socket.packet(encodedPackets, true, flags.volatile);
  110. ids[id] = true;
  111. }
  112. }
  113. }
  114. }
  115. } else {
  116. for (var id in self.sids) {
  117. if (self.sids.hasOwnProperty(id)) {
  118. if (~except.indexOf(id)) continue;
  119. socket = self.nsp.connected[id];
  120. if (socket) socket.packet(encodedPackets, true, flags.volatile);
  121. }
  122. }
  123. }
  124. });
  125. };