broadcast-operator.js 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. exports.RemoteSocket = exports.BroadcastOperator = void 0;
  4. const socket_1 = require("./socket");
  5. const socket_io_parser_1 = require("socket.io-parser");
  6. class BroadcastOperator {
  7. constructor(adapter, rooms = new Set(), exceptRooms = new Set(), flags = {}) {
  8. this.adapter = adapter;
  9. this.rooms = rooms;
  10. this.exceptRooms = exceptRooms;
  11. this.flags = flags;
  12. }
  13. /**
  14. * Targets a room when emitting.
  15. *
  16. * @param room
  17. * @return a new BroadcastOperator instance
  18. * @public
  19. */
  20. to(room) {
  21. const rooms = new Set(this.rooms);
  22. if (Array.isArray(room)) {
  23. room.forEach((r) => rooms.add(r));
  24. }
  25. else {
  26. rooms.add(room);
  27. }
  28. return new BroadcastOperator(this.adapter, rooms, this.exceptRooms, this.flags);
  29. }
  30. /**
  31. * Targets a room when emitting.
  32. *
  33. * @param room
  34. * @return a new BroadcastOperator instance
  35. * @public
  36. */
  37. in(room) {
  38. return this.to(room);
  39. }
  40. /**
  41. * Excludes a room when emitting.
  42. *
  43. * @param room
  44. * @return a new BroadcastOperator instance
  45. * @public
  46. */
  47. except(room) {
  48. const exceptRooms = new Set(this.exceptRooms);
  49. if (Array.isArray(room)) {
  50. room.forEach((r) => exceptRooms.add(r));
  51. }
  52. else {
  53. exceptRooms.add(room);
  54. }
  55. return new BroadcastOperator(this.adapter, this.rooms, exceptRooms, this.flags);
  56. }
  57. /**
  58. * Sets the compress flag.
  59. *
  60. * @param compress - if `true`, compresses the sending data
  61. * @return a new BroadcastOperator instance
  62. * @public
  63. */
  64. compress(compress) {
  65. const flags = Object.assign({}, this.flags, { compress });
  66. return new BroadcastOperator(this.adapter, this.rooms, this.exceptRooms, flags);
  67. }
  68. /**
  69. * Sets a modifier for a subsequent event emission that the event data may be lost if the client is not ready to
  70. * receive messages (because of network slowness or other issues, or because they’re connected through long polling
  71. * and is in the middle of a request-response cycle).
  72. *
  73. * @return a new BroadcastOperator instance
  74. * @public
  75. */
  76. get volatile() {
  77. const flags = Object.assign({}, this.flags, { volatile: true });
  78. return new BroadcastOperator(this.adapter, this.rooms, this.exceptRooms, flags);
  79. }
  80. /**
  81. * Sets a modifier for a subsequent event emission that the event data will only be broadcast to the current node.
  82. *
  83. * @return a new BroadcastOperator instance
  84. * @public
  85. */
  86. get local() {
  87. const flags = Object.assign({}, this.flags, { local: true });
  88. return new BroadcastOperator(this.adapter, this.rooms, this.exceptRooms, flags);
  89. }
  90. /**
  91. * Emits to all clients.
  92. *
  93. * @return Always true
  94. * @public
  95. */
  96. emit(ev, ...args) {
  97. if (socket_1.RESERVED_EVENTS.has(ev)) {
  98. throw new Error(`"${ev}" is a reserved event name`);
  99. }
  100. // set up packet object
  101. const data = [ev, ...args];
  102. const packet = {
  103. type: socket_io_parser_1.PacketType.EVENT,
  104. data: data,
  105. };
  106. if ("function" == typeof data[data.length - 1]) {
  107. throw new Error("Callbacks are not supported when broadcasting");
  108. }
  109. this.adapter.broadcast(packet, {
  110. rooms: this.rooms,
  111. except: this.exceptRooms,
  112. flags: this.flags,
  113. });
  114. return true;
  115. }
  116. /**
  117. * Gets a list of clients.
  118. *
  119. * @public
  120. */
  121. allSockets() {
  122. if (!this.adapter) {
  123. throw new Error("No adapter for this namespace, are you trying to get the list of clients of a dynamic namespace?");
  124. }
  125. return this.adapter.sockets(this.rooms);
  126. }
  127. /**
  128. * Returns the matching socket instances
  129. *
  130. * @public
  131. */
  132. fetchSockets() {
  133. return this.adapter
  134. .fetchSockets({
  135. rooms: this.rooms,
  136. except: this.exceptRooms,
  137. })
  138. .then((sockets) => {
  139. return sockets.map((socket) => {
  140. if (socket instanceof socket_1.Socket) {
  141. // FIXME the TypeScript compiler complains about missing private properties
  142. return socket;
  143. }
  144. else {
  145. return new RemoteSocket(this.adapter, socket);
  146. }
  147. });
  148. });
  149. }
  150. /**
  151. * Makes the matching socket instances join the specified rooms
  152. *
  153. * @param room
  154. * @public
  155. */
  156. socketsJoin(room) {
  157. this.adapter.addSockets({
  158. rooms: this.rooms,
  159. except: this.exceptRooms,
  160. }, Array.isArray(room) ? room : [room]);
  161. }
  162. /**
  163. * Makes the matching socket instances leave the specified rooms
  164. *
  165. * @param room
  166. * @public
  167. */
  168. socketsLeave(room) {
  169. this.adapter.delSockets({
  170. rooms: this.rooms,
  171. except: this.exceptRooms,
  172. }, Array.isArray(room) ? room : [room]);
  173. }
  174. /**
  175. * Makes the matching socket instances disconnect
  176. *
  177. * @param close - whether to close the underlying connection
  178. * @public
  179. */
  180. disconnectSockets(close = false) {
  181. this.adapter.disconnectSockets({
  182. rooms: this.rooms,
  183. except: this.exceptRooms,
  184. }, close);
  185. }
  186. }
  187. exports.BroadcastOperator = BroadcastOperator;
  188. /**
  189. * Expose of subset of the attributes and methods of the Socket class
  190. */
  191. class RemoteSocket {
  192. constructor(adapter, details) {
  193. this.id = details.id;
  194. this.handshake = details.handshake;
  195. this.rooms = new Set(details.rooms);
  196. this.data = details.data;
  197. this.operator = new BroadcastOperator(adapter, new Set([this.id]));
  198. }
  199. emit(ev, ...args) {
  200. return this.operator.emit(ev, ...args);
  201. }
  202. /**
  203. * Joins a room.
  204. *
  205. * @param {String|Array} room - room or array of rooms
  206. * @public
  207. */
  208. join(room) {
  209. return this.operator.socketsJoin(room);
  210. }
  211. /**
  212. * Leaves a room.
  213. *
  214. * @param {String} room
  215. * @public
  216. */
  217. leave(room) {
  218. return this.operator.socketsLeave(room);
  219. }
  220. /**
  221. * Disconnects this client.
  222. *
  223. * @param {Boolean} close - if `true`, closes the underlying connection
  224. * @return {Socket} self
  225. *
  226. * @public
  227. */
  228. disconnect(close = false) {
  229. this.operator.disconnectSockets(close);
  230. return this;
  231. }
  232. }
  233. exports.RemoteSocket = RemoteSocket;