namespace.js 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. "use strict";
  2. var __importDefault = (this && this.__importDefault) || function (mod) {
  3. return (mod && mod.__esModule) ? mod : { "default": mod };
  4. };
  5. Object.defineProperty(exports, "__esModule", { value: true });
  6. exports.Namespace = exports.RESERVED_EVENTS = void 0;
  7. const socket_1 = require("./socket");
  8. const typed_events_1 = require("./typed-events");
  9. const debug_1 = __importDefault(require("debug"));
  10. const broadcast_operator_1 = require("./broadcast-operator");
  11. const debug = (0, debug_1.default)("socket.io:namespace");
  12. exports.RESERVED_EVENTS = new Set(["connect", "connection", "new_namespace"]);
  13. class Namespace extends typed_events_1.StrictEventEmitter {
  14. /**
  15. * Namespace constructor.
  16. *
  17. * @param server instance
  18. * @param name
  19. */
  20. constructor(server, name) {
  21. super();
  22. this.sockets = new Map();
  23. /** @private */
  24. this._fns = [];
  25. /** @private */
  26. this._ids = 0;
  27. this.server = server;
  28. this.name = name;
  29. this._initAdapter();
  30. }
  31. /**
  32. * Initializes the `Adapter` for this nsp.
  33. * Run upon changing adapter by `Server#adapter`
  34. * in addition to the constructor.
  35. *
  36. * @private
  37. */
  38. _initAdapter() {
  39. // @ts-ignore
  40. this.adapter = new (this.server.adapter())(this);
  41. }
  42. /**
  43. * Sets up namespace middleware.
  44. *
  45. * @return self
  46. * @public
  47. */
  48. use(fn) {
  49. this._fns.push(fn);
  50. return this;
  51. }
  52. /**
  53. * Executes the middleware for an incoming client.
  54. *
  55. * @param socket - the socket that will get added
  56. * @param fn - last fn call in the middleware
  57. * @private
  58. */
  59. run(socket, fn) {
  60. const fns = this._fns.slice(0);
  61. if (!fns.length)
  62. return fn(null);
  63. function run(i) {
  64. fns[i](socket, function (err) {
  65. // upon error, short-circuit
  66. if (err)
  67. return fn(err);
  68. // if no middleware left, summon callback
  69. if (!fns[i + 1])
  70. return fn(null);
  71. // go on to next
  72. run(i + 1);
  73. });
  74. }
  75. run(0);
  76. }
  77. /**
  78. * Targets a room when emitting.
  79. *
  80. * @param room
  81. * @return self
  82. * @public
  83. */
  84. to(room) {
  85. return new broadcast_operator_1.BroadcastOperator(this.adapter).to(room);
  86. }
  87. /**
  88. * Targets a room when emitting.
  89. *
  90. * @param room
  91. * @return self
  92. * @public
  93. */
  94. in(room) {
  95. return new broadcast_operator_1.BroadcastOperator(this.adapter).in(room);
  96. }
  97. /**
  98. * Excludes a room when emitting.
  99. *
  100. * @param room
  101. * @return self
  102. * @public
  103. */
  104. except(room) {
  105. return new broadcast_operator_1.BroadcastOperator(this.adapter).except(room);
  106. }
  107. /**
  108. * Adds a new client.
  109. *
  110. * @return {Socket}
  111. * @private
  112. */
  113. _add(client, query, fn) {
  114. debug("adding socket to nsp %s", this.name);
  115. const socket = new socket_1.Socket(this, client, query);
  116. this.run(socket, (err) => {
  117. process.nextTick(() => {
  118. if ("open" == client.conn.readyState) {
  119. if (err) {
  120. if (client.conn.protocol === 3) {
  121. return socket._error(err.data || err.message);
  122. }
  123. else {
  124. return socket._error({
  125. message: err.message,
  126. data: err.data,
  127. });
  128. }
  129. }
  130. // track socket
  131. this.sockets.set(socket.id, socket);
  132. // it's paramount that the internal `onconnect` logic
  133. // fires before user-set events to prevent state order
  134. // violations (such as a disconnection before the connection
  135. // logic is complete)
  136. socket._onconnect();
  137. if (fn)
  138. fn();
  139. // fire user-set events
  140. this.emitReserved("connect", socket);
  141. this.emitReserved("connection", socket);
  142. }
  143. else {
  144. debug("next called after client was closed - ignoring socket");
  145. }
  146. });
  147. });
  148. return socket;
  149. }
  150. /**
  151. * Removes a client. Called by each `Socket`.
  152. *
  153. * @private
  154. */
  155. _remove(socket) {
  156. if (this.sockets.has(socket.id)) {
  157. this.sockets.delete(socket.id);
  158. }
  159. else {
  160. debug("ignoring remove for %s", socket.id);
  161. }
  162. }
  163. /**
  164. * Emits to all clients.
  165. *
  166. * @return Always true
  167. * @public
  168. */
  169. emit(ev, ...args) {
  170. return new broadcast_operator_1.BroadcastOperator(this.adapter).emit(ev, ...args);
  171. }
  172. /**
  173. * Sends a `message` event to all clients.
  174. *
  175. * @return self
  176. * @public
  177. */
  178. send(...args) {
  179. this.emit("message", ...args);
  180. return this;
  181. }
  182. /**
  183. * Sends a `message` event to all clients.
  184. *
  185. * @return self
  186. * @public
  187. */
  188. write(...args) {
  189. this.emit("message", ...args);
  190. return this;
  191. }
  192. /**
  193. * Emit a packet to other Socket.IO servers
  194. *
  195. * @param ev - the event name
  196. * @param args - an array of arguments, which may include an acknowledgement callback at the end
  197. * @public
  198. */
  199. serverSideEmit(ev, ...args) {
  200. if (exports.RESERVED_EVENTS.has(ev)) {
  201. throw new Error(`"${ev}" is a reserved event name`);
  202. }
  203. args.unshift(ev);
  204. this.adapter.serverSideEmit(args);
  205. return true;
  206. }
  207. /**
  208. * Called when a packet is received from another Socket.IO server
  209. *
  210. * @param args - an array of arguments, which may include an acknowledgement callback at the end
  211. *
  212. * @private
  213. */
  214. _onServerSideEmit(args) {
  215. super.emitUntyped.apply(this, args);
  216. }
  217. /**
  218. * Gets a list of clients.
  219. *
  220. * @return self
  221. * @public
  222. */
  223. allSockets() {
  224. return new broadcast_operator_1.BroadcastOperator(this.adapter).allSockets();
  225. }
  226. /**
  227. * Sets the compress flag.
  228. *
  229. * @param compress - if `true`, compresses the sending data
  230. * @return self
  231. * @public
  232. */
  233. compress(compress) {
  234. return new broadcast_operator_1.BroadcastOperator(this.adapter).compress(compress);
  235. }
  236. /**
  237. * Sets a modifier for a subsequent event emission that the event data may be lost if the client is not ready to
  238. * receive messages (because of network slowness or other issues, or because they’re connected through long polling
  239. * and is in the middle of a request-response cycle).
  240. *
  241. * @return self
  242. * @public
  243. */
  244. get volatile() {
  245. return new broadcast_operator_1.BroadcastOperator(this.adapter).volatile;
  246. }
  247. /**
  248. * Sets a modifier for a subsequent event emission that the event data will only be broadcast to the current node.
  249. *
  250. * @return self
  251. * @public
  252. */
  253. get local() {
  254. return new broadcast_operator_1.BroadcastOperator(this.adapter).local;
  255. }
  256. /**
  257. * Returns the matching socket instances
  258. *
  259. * @public
  260. */
  261. fetchSockets() {
  262. return new broadcast_operator_1.BroadcastOperator(this.adapter).fetchSockets();
  263. }
  264. /**
  265. * Makes the matching socket instances join the specified rooms
  266. *
  267. * @param room
  268. * @public
  269. */
  270. socketsJoin(room) {
  271. return new broadcast_operator_1.BroadcastOperator(this.adapter).socketsJoin(room);
  272. }
  273. /**
  274. * Makes the matching socket instances leave the specified rooms
  275. *
  276. * @param room
  277. * @public
  278. */
  279. socketsLeave(room) {
  280. return new broadcast_operator_1.BroadcastOperator(this.adapter).socketsLeave(room);
  281. }
  282. /**
  283. * Makes the matching socket instances disconnect
  284. *
  285. * @param close - whether to close the underlying connection
  286. * @public
  287. */
  288. disconnectSockets(close = false) {
  289. return new broadcast_operator_1.BroadcastOperator(this.adapter).disconnectSockets(close);
  290. }
  291. }
  292. exports.Namespace = Namespace;